@agoric/orchestration 0.1.1-dev-acbb5da.0 → 0.1.1-dev-5fb1074.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 +18 -17
- package/src/examples/auto-stake-it.contract.d.ts.map +1 -1
- package/src/examples/auto-stake-it.contract.js +1 -1
- package/src/examples/basic-flows.contract.d.ts.map +1 -1
- package/src/examples/basic-flows.contract.js +1 -1
- package/src/examples/send-anywhere.contract.d.ts +11 -8
- package/src/examples/send-anywhere.contract.d.ts.map +1 -1
- package/src/examples/send-anywhere.contract.js +5 -4
- package/src/examples/staking-combinations.contract.d.ts.map +1 -1
- package/src/examples/staking-combinations.contract.js +1 -1
- package/src/examples/swap.contract.d.ts.map +1 -1
- package/src/examples/swap.contract.js +1 -1
- package/src/examples/unbond.contract.d.ts.map +1 -1
- package/src/examples/unbond.contract.js +1 -1
- package/src/exos/cosmos-orchestration-account.d.ts +14 -10
- package/src/exos/cosmos-orchestration-account.d.ts.map +1 -1
- package/src/exos/cosmos-orchestration-account.js +18 -13
- package/src/exos/local-chain-facade.d.ts +1 -1
- package/src/exos/local-chain-facade.d.ts.map +1 -1
- package/src/exos/local-chain-facade.js +9 -7
- package/src/exos/local-orchestration-account.d.ts +2 -2
- package/src/exos/local-orchestration-account.d.ts.map +1 -1
- package/src/exos/local-orchestration-account.js +11 -5
- package/src/exos/remote-chain-facade.d.ts +1 -1
- package/src/exos/remote-chain-facade.d.ts.map +1 -1
- package/src/exos/remote-chain-facade.js +12 -8
- package/src/facade.d.ts +1 -4
- package/src/facade.d.ts.map +1 -1
- package/src/facade.js +2 -9
- package/src/fixtures/query-flows.contract.d.ts.map +1 -1
- package/src/fixtures/query-flows.contract.js +1 -1
- package/src/utils/start-helper.d.ts +10 -2
- package/src/utils/start-helper.d.ts.map +1 -1
- package/src/utils/start-helper.js +15 -6
- package/tools/ibc-mocks.d.ts +116 -0
- package/tools/ibc-mocks.d.ts.map +1 -0
- package/tools/ibc-mocks.ts +262 -0
- package/tools/make-test-address.d.ts +2 -0
- package/tools/make-test-address.d.ts.map +1 -0
- package/tools/make-test-address.js +21 -0
- package/tools/protobuf-decoder.d.ts +19 -0
- package/tools/protobuf-decoder.d.ts.map +1 -0
- package/tools/protobuf-decoder.js +153 -0
package/src/facade.js
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
import { assertAllDefined, deepMapObject } from '@agoric/internal';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @import {AsyncFlowTools, GuestInterface, HostArgs
|
|
5
|
+
* @import {AsyncFlowTools, GuestInterface, HostArgs} from '@agoric/async-flow';
|
|
6
6
|
* @import {Zone} from '@agoric/zone';
|
|
7
7
|
* @import {Vow, VowTools} from '@agoric/vow';
|
|
8
8
|
* @import {TimerService} from '@agoric/time';
|
|
9
|
-
* @import {RecorderKit, MakeRecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js'.
|
|
10
9
|
* @import {HostOrchestrator} from './exos/orchestrator.js';
|
|
11
10
|
* @import {Remote} from '@agoric/internal';
|
|
12
11
|
* @import {CosmosInterchainService} from './exos/exo-interfaces.js';
|
|
13
|
-
* @import {
|
|
12
|
+
* @import {OrchestrationFlow, Orchestrator} from './types.js';
|
|
14
13
|
*/
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -31,9 +30,7 @@ import { assertAllDefined, deepMapObject } from '@agoric/internal';
|
|
|
31
30
|
* zone: Zone;
|
|
32
31
|
* timerService: Remote<TimerService>;
|
|
33
32
|
* zcf: ZCF;
|
|
34
|
-
* storageNode: Remote<StorageNode>;
|
|
35
33
|
* orchestrationService: Remote<CosmosInterchainService>;
|
|
36
|
-
* makeRecorderKit: MakeRecorderKit;
|
|
37
34
|
* makeOrchestrator: () => HostOrchestrator;
|
|
38
35
|
* vowTools: VowTools;
|
|
39
36
|
* asyncFlowTools: AsyncFlowTools;
|
|
@@ -43,9 +40,7 @@ export const makeOrchestrationFacade = ({
|
|
|
43
40
|
zone,
|
|
44
41
|
timerService,
|
|
45
42
|
zcf,
|
|
46
|
-
storageNode,
|
|
47
43
|
orchestrationService,
|
|
48
|
-
makeRecorderKit,
|
|
49
44
|
makeOrchestrator,
|
|
50
45
|
vowTools,
|
|
51
46
|
asyncFlowTools,
|
|
@@ -54,9 +49,7 @@ export const makeOrchestrationFacade = ({
|
|
|
54
49
|
zone,
|
|
55
50
|
timerService,
|
|
56
51
|
zcf,
|
|
57
|
-
storageNode,
|
|
58
52
|
orchestrationService,
|
|
59
|
-
makeRecorderKit,
|
|
60
53
|
makeOrchestrator,
|
|
61
54
|
vowTools,
|
|
62
55
|
asyncFlowTools,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-flows.contract.d.ts","sourceRoot":"","sources":["query-flows.contract.js"],"names":[],"mappings":"AAkEA;gBAjDiB,UAAU;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"query-flows.contract.d.ts","sourceRoot":"","sources":["query-flows.contract.js"],"names":[],"mappings":"AAkEA;gBAjDiB,UAAU;;;;;;;;;;;;;;;;;;GAiDoD;2BAGjE,OAAO,KAAK;yCA3DY,2BAA2B"}
|
|
@@ -64,7 +64,7 @@ const contract = async (zcf, _privateArgs, zone, { orchestrateAll }) => {
|
|
|
64
64
|
return { publicFacet };
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
export const start = withOrchestration(contract);
|
|
67
|
+
export const start = withOrchestration(contract, { publishAccountInfo: true });
|
|
68
68
|
harden(start);
|
|
69
69
|
|
|
70
70
|
/** @typedef {typeof start} QueryFlowsSF */
|
|
@@ -69,14 +69,22 @@ export function provideOrchestration(zcf: ZCF, baggage: Baggage, remotePowers: O
|
|
|
69
69
|
};
|
|
70
70
|
export function withOrchestration<CT extends Record<string, unknown>, PA extends OrchestrationPowers & {
|
|
71
71
|
marshaller: Marshaller;
|
|
72
|
-
}, R>(contractFn: (zcf: ZCF<CT>, privateArgs: PA, zone: Zone, tools: OrchestrationTools) => Promise<R
|
|
72
|
+
}, R>(contractFn: (zcf: ZCF<CT>, privateArgs: PA, zone: Zone, tools: OrchestrationTools) => Promise<R>, opts?: WithOrchestrationOpts): (zcf: ZCF<CT>, privateArgs: PA, baggage: Baggage) => Promise<R>;
|
|
73
73
|
export type OrchestrationPowers = {
|
|
74
74
|
localchain: Remote<LocalChain>;
|
|
75
75
|
orchestrationService: Remote<CosmosInterchainService>;
|
|
76
|
-
storageNode
|
|
76
|
+
storageNode?: Remote<StorageNode>;
|
|
77
77
|
timerService: Remote<TimerService>;
|
|
78
78
|
agoricNames: Remote<NameHub>;
|
|
79
79
|
};
|
|
80
|
+
export type WithOrchestrationOpts = {
|
|
81
|
+
/**
|
|
82
|
+
* - Controls whether account
|
|
83
|
+
* information (address, channel identifiers for ICAs) should be automatically
|
|
84
|
+
* published to vstorage
|
|
85
|
+
*/
|
|
86
|
+
publishAccountInfo?: boolean | undefined;
|
|
87
|
+
};
|
|
80
88
|
export type OrchestrationTools = Omit<ReturnType<typeof provideOrchestration>, "zone">;
|
|
81
89
|
import type { Baggage } from '@agoric/vat-data';
|
|
82
90
|
import type { Zone } from '@agoric/zone';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-helper.d.ts","sourceRoot":"","sources":["start-helper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start-helper.d.ts","sourceRoot":"","sources":["start-helper.js"],"names":[],"mappings":"AAqDO,0CANI,GAAG,WACH,OAAO,gBACP,mBAAmB,cACnB,UAAU;+BAiGR,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;sBA1CD,CAAC;;;;;;;;;;;;;;;;;;;;;sBAuHykY,CAAC;;;;;;;;;;;;;;;;;;;;EA5C1lY;AA+BM,kCAfgC,EAAE,SAA3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,EAGhC,EAAE,SAFM,mBAAmB,GAAG;IAC/B,UAAU,EAAE,UAAU,CAAC;CACvB,EACQ,CAAC,cACH,CACN,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EACZ,WAAW,EAAE,EAAE,EACf,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,kBAAkB,KACtB,OAAO,CAAC,CAAC,CAAC,SACP,qBAAqB,GACnB,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAczE;kCArMU;IACR,UAAU,EAAE,OAAO,UAAU,CAAC,CAAC;IAC/B,oBAAoB,EAAE,OAAO,uBAAuB,CAAC,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,WAAW,CAAC,CAAC;IAClC,YAAY,EAAE,OAAO,YAAY,CAAC,CAAC;IACnC,WAAW,EAAE,OAAO,OAAO,CAAC,CAAC;CAC9B;;;;;;;;;iCAwJU,IAAI,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,EAAE,MAAM,CAAC;6BAtKzC,kBAAkB;0BAGrB,cAAc;gCALR,gCAAgC;4BAIpC,aAAa;6CAEI,2BAA2B;kCALtC,cAAc;6BAEnB,cAAc"}
|
|
@@ -14,7 +14,7 @@ import { makeZcfTools } from './zcf-tools.js';
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @import {LocalChain} from '@agoric/vats/src/localchain.js';
|
|
17
|
-
* @import {TimerService
|
|
17
|
+
* @import {TimerService} from '@agoric/time';
|
|
18
18
|
* @import {Baggage} from '@agoric/vat-data';
|
|
19
19
|
* @import {NameHub} from '@agoric/vats';
|
|
20
20
|
* @import {Remote} from '@agoric/vow';
|
|
@@ -26,12 +26,19 @@ import { makeZcfTools } from './zcf-tools.js';
|
|
|
26
26
|
* @typedef {{
|
|
27
27
|
* localchain: Remote<LocalChain>;
|
|
28
28
|
* orchestrationService: Remote<CosmosInterchainService>;
|
|
29
|
-
* storageNode
|
|
29
|
+
* storageNode?: Remote<StorageNode>;
|
|
30
30
|
* timerService: Remote<TimerService>;
|
|
31
31
|
* agoricNames: Remote<NameHub>;
|
|
32
32
|
* }} OrchestrationPowers
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {object} WithOrchestrationOpts
|
|
37
|
+
* @property {boolean} [publishAccountInfo] - Controls whether account
|
|
38
|
+
* information (address, channel identifiers for ICAs) should be automatically
|
|
39
|
+
* published to vstorage
|
|
40
|
+
*/
|
|
41
|
+
|
|
35
42
|
/**
|
|
36
43
|
* Helper that a contract start function can use to set up the objects needed
|
|
37
44
|
* for orchestration.
|
|
@@ -144,7 +151,6 @@ export const provideOrchestration = (
|
|
|
144
151
|
makeOrchestrationFacade({
|
|
145
152
|
zone,
|
|
146
153
|
zcf,
|
|
147
|
-
makeRecorderKit,
|
|
148
154
|
makeOrchestrator,
|
|
149
155
|
asyncFlowTools,
|
|
150
156
|
vowTools,
|
|
@@ -199,16 +205,19 @@ harden(provideOrchestration);
|
|
|
199
205
|
* zone: Zone,
|
|
200
206
|
* tools: OrchestrationTools,
|
|
201
207
|
* ) => Promise<R>} contractFn
|
|
208
|
+
* @param {WithOrchestrationOpts} [opts]
|
|
202
209
|
* @returns {(zcf: ZCF<CT>, privateArgs: PA, baggage: Baggage) => Promise<R>} a
|
|
203
210
|
* Zoe start function
|
|
204
211
|
*/
|
|
205
212
|
export const withOrchestration =
|
|
206
|
-
contractFn => async (zcf, privateArgs, baggage) => {
|
|
213
|
+
(contractFn, opts) => async (zcf, privateArgs, baggage) => {
|
|
214
|
+
const { marshaller, ...allOrchPowers } = privateArgs;
|
|
215
|
+
const { storageNode: _, ...requiredOrchPowers } = allOrchPowers;
|
|
207
216
|
const { zone, ...tools } = provideOrchestration(
|
|
208
217
|
zcf,
|
|
209
218
|
baggage,
|
|
210
|
-
|
|
211
|
-
|
|
219
|
+
opts?.publishAccountInfo ? allOrchPowers : requiredOrchPowers,
|
|
220
|
+
marshaller,
|
|
212
221
|
);
|
|
213
222
|
return contractFn(zcf, privateArgs, zone, tools);
|
|
214
223
|
};
|
|
@@ -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 @@
|
|
|
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"}
|