@agoric/vats 0.15.1 → 0.15.2-calypso-dev-84eb287.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/README.md +3 -0
- package/index.d.ts +6 -0
- package/index.d.ts.map +1 -0
- package/index.js +9 -0
- package/package.json +43 -48
- package/scripts/build-bundles.js +19 -0
- package/src/bridge-target.d.ts +193 -0
- package/src/bridge-target.d.ts.map +1 -0
- package/src/bridge-target.js +316 -0
- package/src/bridge.d.ts +14 -4
- package/src/bridge.d.ts.map +1 -1
- package/src/bridge.js +45 -16
- package/src/centralSupply.d.ts +3 -3
- package/src/centralSupply.d.ts.map +1 -1
- package/src/centralSupply.js +3 -5
- package/src/core/README.md +1 -1
- package/src/core/basic-behaviors.d.ts +24 -39
- package/src/core/basic-behaviors.d.ts.map +1 -1
- package/src/core/basic-behaviors.js +63 -63
- package/src/core/boot-chain.d.ts +178 -44
- package/src/core/boot-chain.d.ts.map +1 -1
- package/src/core/boot-chain.js +5 -5
- package/src/core/boot-sim.d.ts +5 -43
- package/src/core/boot-sim.d.ts.map +1 -1
- package/src/core/boot-sim.js +3 -4
- package/src/core/boot-solo.d.ts +5 -43
- package/src/core/boot-solo.d.ts.map +1 -1
- package/src/core/boot-solo.js +4 -5
- package/src/core/chain-behaviors.d.ts +10 -26
- package/src/core/chain-behaviors.d.ts.map +1 -1
- package/src/core/chain-behaviors.js +38 -42
- package/src/core/client-behaviors.d.ts +2 -1
- package/src/core/client-behaviors.d.ts.map +1 -1
- package/src/core/client-behaviors.js +6 -5
- package/src/core/core-eval-env.d.ts +40 -0
- package/src/core/demoIssuers.d.ts +24 -26
- package/src/core/demoIssuers.d.ts.map +1 -1
- package/src/core/demoIssuers.js +37 -37
- package/src/core/lib-boot.d.ts +17 -53
- package/src/core/lib-boot.d.ts.map +1 -1
- package/src/core/lib-boot.js +52 -60
- package/src/core/promise-space.d.ts +4 -7
- package/src/core/promise-space.d.ts.map +1 -1
- package/src/core/promise-space.js +15 -16
- package/src/core/sim-behaviors.d.ts +3 -3
- package/src/core/sim-behaviors.d.ts.map +1 -1
- package/src/core/sim-behaviors.js +1 -1
- package/src/core/startWalletFactory.d.ts +23 -27
- package/src/core/startWalletFactory.d.ts.map +1 -1
- package/src/core/startWalletFactory.js +32 -18
- package/src/core/types-ambient.d.ts +538 -0
- package/src/core/types-ambient.js +1 -0
- package/src/core/utils.d.ts +47 -92
- package/src/core/utils.d.ts.map +1 -1
- package/src/core/utils.js +58 -50
- package/src/crc.d.ts +2 -6
- package/src/crc.d.ts.map +1 -1
- package/src/crc.js +5 -16
- package/src/ibc.d.ts +30 -35
- package/src/ibc.d.ts.map +1 -1
- package/src/ibc.js +740 -491
- package/src/lib-board.d.ts +49 -121
- package/src/lib-board.d.ts.map +1 -1
- package/src/lib-board.js +49 -50
- package/src/localchain.d.ts +195 -0
- package/src/localchain.d.ts.map +1 -0
- package/src/localchain.js +324 -0
- package/src/mintHolder.d.ts +6 -4
- package/src/mintHolder.d.ts.map +1 -1
- package/src/mintHolder.js +19 -21
- package/src/nameHub.d.ts +27 -5
- package/src/nameHub.d.ts.map +1 -1
- package/src/nameHub.js +33 -26
- package/src/priceAuthorityRegistry.d.ts +21 -0
- package/src/priceAuthorityRegistry.d.ts.map +1 -0
- package/src/priceAuthorityRegistry.js +220 -0
- package/src/proposals/kread-proposal.d.ts +15 -0
- package/src/proposals/kread-proposal.d.ts.map +1 -0
- package/src/proposals/kread-proposal.js +24 -0
- package/src/proposals/localchain-proposal.d.ts +62 -0
- package/src/proposals/localchain-proposal.d.ts.map +1 -0
- package/src/proposals/localchain-proposal.js +128 -0
- package/src/proposals/localchain-test.d.ts +25 -0
- package/src/proposals/localchain-test.d.ts.map +1 -0
- package/src/proposals/localchain-test.js +89 -0
- package/src/proposals/namesByAddress-fix-proposal.d.ts +22 -0
- package/src/proposals/namesByAddress-fix-proposal.d.ts.map +1 -0
- package/src/proposals/namesByAddress-fix-proposal.js +55 -0
- package/src/proposals/network-proposal.d.ts +23 -8
- package/src/proposals/network-proposal.d.ts.map +1 -1
- package/src/proposals/network-proposal.js +90 -65
- package/src/proposals/probeZcfBundle.d.ts +26 -0
- package/src/proposals/probeZcfBundle.d.ts.map +1 -0
- package/src/proposals/probeZcfBundle.js +72 -0
- package/src/proposals/restart-vats-proposal.d.ts +4 -2
- package/src/proposals/restart-vats-proposal.d.ts.map +1 -1
- package/src/proposals/restart-vats-proposal.js +20 -8
- package/src/proposals/transfer-proposal.d.ts +37 -0
- package/src/proposals/transfer-proposal.d.ts.map +1 -0
- package/src/proposals/transfer-proposal.js +115 -0
- package/src/proposals/upgrade-bank-proposal.d.ts +27 -0
- package/src/proposals/upgrade-bank-proposal.d.ts.map +1 -0
- package/src/proposals/upgrade-bank-proposal.js +42 -0
- package/src/proposals/upgrade-provisionPool-proposal.d.ts +27 -0
- package/src/proposals/upgrade-provisionPool-proposal.d.ts.map +1 -0
- package/src/proposals/upgrade-provisionPool-proposal.js +67 -0
- package/src/proposals/upgrade-zoe-proposal.d.ts +27 -0
- package/src/proposals/upgrade-zoe-proposal.d.ts.map +1 -0
- package/src/proposals/upgrade-zoe-proposal.js +42 -0
- package/src/proposals/vtransfer-echoer.d.ts +24 -0
- package/src/proposals/vtransfer-echoer.d.ts.map +1 -0
- package/src/proposals/vtransfer-echoer.js +42 -0
- package/src/proposals/zcf-only-proposal.d.ts +33 -0
- package/src/proposals/zcf-only-proposal.d.ts.map +1 -0
- package/src/proposals/zcf-only-proposal.js +36 -0
- package/src/proposals/zcf-proposal.d.ts +30 -0
- package/src/proposals/zcf-proposal.d.ts.map +1 -0
- package/src/proposals/zcf-proposal.js +50 -0
- package/src/repl.d.ts +3 -3
- package/src/repl.d.ts.map +1 -1
- package/src/repl.js +11 -5
- package/src/transfer.d.ts +111 -0
- package/src/transfer.d.ts.map +1 -0
- package/src/transfer.js +260 -0
- package/src/types.d.ts +237 -105
- package/src/types.js +1 -97
- package/src/vat-agoricNames.d.ts +4 -4
- package/src/vat-agoricNames.d.ts.map +1 -1
- package/src/vat-agoricNames.js +2 -4
- package/src/vat-bank.d.ts +217 -149
- package/src/vat-bank.d.ts.map +1 -1
- package/src/vat-bank.js +96 -68
- package/src/vat-board.d.ts +24 -24
- package/src/vat-board.d.ts.map +1 -1
- package/src/vat-board.js +0 -1
- package/src/vat-bridge.d.ts +9 -23
- package/src/vat-bridge.d.ts.map +1 -1
- package/src/vat-bridge.js +1 -2
- package/src/vat-ibc.d.ts +16 -4
- package/src/vat-ibc.d.ts.map +1 -1
- package/src/vat-ibc.js +20 -9
- package/src/vat-localchain.d.ts +37 -0
- package/src/vat-localchain.d.ts.map +1 -0
- package/src/vat-localchain.js +29 -0
- package/src/vat-mints.d.ts +31 -31
- package/src/vat-mints.d.ts.map +1 -1
- package/src/vat-mints.js +6 -7
- package/src/vat-network.d.ts +69 -1
- package/src/vat-network.d.ts.map +1 -1
- package/src/vat-network.js +45 -3
- package/src/vat-priceAuthority.d.ts +4 -4
- package/src/vat-priceAuthority.d.ts.map +1 -1
- package/src/vat-priceAuthority.js +1 -1
- package/src/vat-provisioning.d.ts +6 -6
- package/src/vat-provisioning.d.ts.map +1 -1
- package/src/vat-provisioning.js +15 -12
- package/src/vat-transfer.d.ts +81 -0
- package/src/vat-transfer.d.ts.map +1 -0
- package/src/vat-transfer.js +63 -0
- package/src/vat-zoe.d.ts +4 -1
- package/src/vat-zoe.d.ts.map +1 -1
- package/src/vat-zoe.js +10 -2
- package/src/virtual-purse.d.ts +46 -21
- package/src/virtual-purse.d.ts.map +1 -1
- package/src/virtual-purse.js +57 -46
- package/src/walletFlags.d.ts +2 -2
- package/src/walletFlags.js +1 -2
- package/tools/bank-utils.d.ts +20 -0
- package/tools/bank-utils.d.ts.map +1 -0
- package/tools/bank-utils.js +92 -0
- package/tools/board-utils.d.ts +39 -0
- package/tools/board-utils.d.ts.map +1 -0
- package/tools/board-utils.js +92 -0
- package/tools/boot-test-utils.d.ts +88 -0
- package/tools/boot-test-utils.d.ts.map +1 -0
- package/tools/boot-test-utils.js +157 -0
- package/tools/fake-bridge.d.ts +18 -0
- package/tools/fake-bridge.d.ts.map +1 -0
- package/tools/fake-bridge.js +289 -0
- package/tools/ibc-utils.d.ts +29 -0
- package/tools/ibc-utils.d.ts.map +1 -0
- package/tools/ibc-utils.js +115 -0
- package/decentral-core-config.json +0 -66
- package/decentral-demo-config.json +0 -155
- package/decentral-devnet-config.json +0 -216
- package/decentral-itest-vaults-config.json +0 -210
- package/decentral-main-vaults-config.json +0 -229
- package/decentral-test-vaults-config.json +0 -195
- package/demo-proposals.json +0 -5
- package/exported.js +0 -1
- package/jsconfig.build.json +0 -12
- package/jsconfig.json +0 -13
- package/src/core/types.d.ts +0 -764
- package/src/core/types.d.ts.map +0 -1
- package/src/core/types.js +0 -347
- package/src/provisionPool.d.ts +0 -164
- package/src/provisionPool.d.ts.map +0 -1
- package/src/provisionPool.js +0 -113
- package/src/provisionPoolKit.d.ts +0 -392
- package/src/provisionPoolKit.d.ts.map +0 -1
- package/src/provisionPoolKit.js +0 -464
- package/src/tokens.d.ts +0 -36
- package/src/tokens.d.ts.map +0 -1
- package/src/tokens.js +0 -37
- package/src/types.d.ts.map +0 -1
- package/src/vat-sharing.d.ts +0 -54
- package/src/vat-sharing.d.ts.map +0 -1
- package/src/vat-sharing.js +0 -14
package/src/ibc.js
CHANGED
|
@@ -1,192 +1,110 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
dataToBase64,
|
|
5
|
-
base64ToBytes,
|
|
6
|
-
} from '@agoric/swingset-vat/src/vats/network/index.js';
|
|
7
|
-
import { makeScalarMapStore, makeLegacyMap } from '@agoric/store';
|
|
8
|
-
import { makePromiseKit } from '@endo/promise-kit';
|
|
9
3
|
import { assert, details as X, Fail } from '@agoric/assert';
|
|
10
|
-
import {
|
|
4
|
+
import { E } from '@endo/far';
|
|
11
5
|
|
|
12
|
-
import '@agoric/
|
|
13
|
-
import '@agoric/swingset-vat/src/vats/network/types.js';
|
|
6
|
+
import { byteSourceToBase64, base64ToBytes } from '@agoric/network';
|
|
14
7
|
|
|
15
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
localAddrToPortID,
|
|
10
|
+
decodeRemoteIbcAddress,
|
|
11
|
+
encodeLocalIbcAddress,
|
|
12
|
+
encodeRemoteIbcAddress,
|
|
13
|
+
} from '../tools/ibc-utils.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @import {LocalIbcAddress, RemoteIbcAddress} from '../tools/ibc-utils.js';
|
|
17
|
+
* @import {AttemptDescription} from '@agoric/network';
|
|
18
|
+
*/
|
|
16
19
|
|
|
17
20
|
// CAVEAT: IBC acks cannot be empty, as the Cosmos IAVL tree cannot represent
|
|
18
21
|
// empty acknowledgements as distinct from unacknowledged packets.
|
|
19
22
|
const DEFAULT_ACKNOWLEDGEMENT = '\x00';
|
|
20
23
|
|
|
21
|
-
// Default timeout after
|
|
22
|
-
const DEFAULT_PACKET_TIMEOUT_NS =
|
|
24
|
+
// Default timeout after 60 minutes.
|
|
25
|
+
const DEFAULT_PACKET_TIMEOUT_NS = 60n * 60n * 1_000_000_000n;
|
|
23
26
|
|
|
24
27
|
/**
|
|
25
|
-
* @
|
|
28
|
+
* @import {Endpoint, Connection, ConnectionHandler, InboundAttempt, Bytes, ProtocolHandler, ProtocolImpl} from '@agoric/network';
|
|
29
|
+
* @import {BridgeHandler, ScopedBridgeManager, ConnectingInfo, IBCChannelID, IBCChannelOrdering, IBCEvent, IBCPacket, IBCPortID, IBCDowncallPacket, IBCDowncallMethod, IBCDowncall, IBCBridgeEvent} from './types.js';
|
|
30
|
+
* @import {Zone} from '@agoric/base-zone';
|
|
31
|
+
* @import {PromiseVow, Remote, VowKit, VowResolver, VowTools} from '@agoric/vow';
|
|
26
32
|
*/
|
|
27
33
|
|
|
28
|
-
/**
|
|
29
|
-
* @typedef {string} IBCPortID
|
|
30
|
-
* @typedef {string} IBCChannelID
|
|
31
|
-
* @typedef {string} IBCConnectionID
|
|
32
|
-
*/
|
|
34
|
+
/** @typedef {VowKit<AttemptDescription>} OnConnectP */
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
|
-
* @typedef {
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
37
|
+
* @typedef {Omit<
|
|
38
|
+
* ConnectingInfo,
|
|
39
|
+
* 'counterparty' | 'channelID' | 'counterpartyVersion'
|
|
40
|
+
* > & {
|
|
41
|
+
* localAddr: Endpoint;
|
|
42
|
+
* onConnectP: OnConnectP;
|
|
43
|
+
* counterparty: { port_id: string };
|
|
44
|
+
* }} Outbound
|
|
41
45
|
*/
|
|
42
46
|
|
|
47
|
+
// FIXME(TS9006) remove 'any'
|
|
43
48
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @param {typeof import('@endo/far').E} E
|
|
48
|
-
* @param {(method: string, params: any) => Promise<any>} rawCallIBCDevice
|
|
49
|
-
* @returns {ProtocolHandler & BridgeHandler} Protocol/Bridge handler
|
|
49
|
+
* @param {Zone} zone
|
|
50
|
+
* @returns {any}
|
|
50
51
|
*/
|
|
51
|
-
export
|
|
52
|
-
// Nonce for creating port identifiers.
|
|
53
|
-
let lastPortID = 0;
|
|
54
|
-
|
|
55
|
-
const callIBCDevice = (method, params) => {
|
|
56
|
-
console.info('IBC downcall', method, params);
|
|
57
|
-
return rawCallIBCDevice(method, params);
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* @type {MapStore<string, Promise<Connection>>}
|
|
61
|
-
*/
|
|
62
|
-
const channelKeyToConnP = makeScalarMapStore('CHANNEL:PORT');
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @typedef {object} Counterparty
|
|
66
|
-
* @property {string} port_id
|
|
67
|
-
* @property {string} channel_id
|
|
68
|
-
*
|
|
69
|
-
* @typedef {object} ConnectingInfo
|
|
70
|
-
* @property {'ORDERED'|'UNORDERED'} order
|
|
71
|
-
* @property {string[]} connectionHops
|
|
72
|
-
* @property {string} portID
|
|
73
|
-
* @property {string} channelID
|
|
74
|
-
* @property {Counterparty} counterparty
|
|
75
|
-
* @property {string} version
|
|
76
|
-
*
|
|
77
|
-
* @typedef {PromiseRecord<AttemptDescription>} OnConnectP
|
|
78
|
-
* @typedef {Omit<ConnectingInfo, 'counterparty' | 'channelID'> & {
|
|
79
|
-
* localAddr: Endpoint, onConnectP: OnConnectP
|
|
80
|
-
* counterparty: { port_id: string },
|
|
81
|
-
* }} Outbound
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @type {LegacyMap<string, Array<Outbound>>}
|
|
86
|
-
*/
|
|
87
|
-
// Legacy because it holds a mutable Javascript Array
|
|
88
|
-
const srcPortToOutbounds = makeLegacyMap('SRC-PORT');
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @type {MapStore<string, ConnectingInfo>}
|
|
92
|
-
*/
|
|
93
|
-
const channelKeyToInfo = makeScalarMapStore('CHANNEL:PORT');
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @type {MapStore<string, Promise<InboundAttempt>>}
|
|
97
|
-
*/
|
|
98
|
-
const channelKeyToAttemptP = makeScalarMapStore('CHANNEL:PORT');
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @type {LegacyMap<string, LegacyMap<number, PromiseRecord<Bytes>>>}
|
|
102
|
-
*/
|
|
103
|
-
// Legacy because it holds a LegacyMap
|
|
104
|
-
const channelKeyToSeqAck = makeLegacyMap('CHANNEL:PORT');
|
|
105
|
-
|
|
52
|
+
export const prepareIBCConnectionHandler = zone => {
|
|
106
53
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* @param {
|
|
110
|
-
* @param {
|
|
111
|
-
* @param {
|
|
112
|
-
*/
|
|
113
|
-
async function ibcSendPacket(
|
|
114
|
-
packet,
|
|
115
|
-
seqToAck,
|
|
116
|
-
relativeTimeoutNs = DEFAULT_PACKET_TIMEOUT_NS,
|
|
117
|
-
) {
|
|
118
|
-
// Make a kernel call to do the send.
|
|
119
|
-
const fullPacket = await callIBCDevice('sendPacket', {
|
|
120
|
-
packet,
|
|
121
|
-
relativeTimeoutNs,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Extract the actual sequence number from the return.
|
|
125
|
-
const { sequence } = fullPacket;
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* @type {PromiseRecord<Bytes>}
|
|
129
|
-
*/
|
|
130
|
-
const ackDeferred = makePromiseKit();
|
|
131
|
-
|
|
132
|
-
// Register the ack resolver/rejector with this sequence number.
|
|
133
|
-
seqToAck.init(sequence, ackDeferred);
|
|
134
|
-
return ackDeferred.promise;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @param {string} channelID
|
|
139
|
-
* @param {string} portID
|
|
140
|
-
* @param {string} rChannelID
|
|
141
|
-
* @param {string} rPortID
|
|
142
|
-
* @param {'ORDERED'|'UNORDERED'} order
|
|
54
|
+
* @param {IBCChannelID} channelID
|
|
55
|
+
* @param {IBCPortID} portID
|
|
56
|
+
* @param {IBCChannelID} rChannelID
|
|
57
|
+
* @param {IBCPortID} rPortID
|
|
58
|
+
* @param {IBCChannelOrdering} order
|
|
143
59
|
* @returns {ConnectionHandler}
|
|
144
60
|
*/
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
rChannelID,
|
|
149
|
-
rPortID,
|
|
150
|
-
order,
|
|
151
|
-
) {
|
|
152
|
-
const channelKey = `${channelID}:${portID}`;
|
|
153
|
-
// Legacy because it holds a PromiseRecord
|
|
154
|
-
const seqToAck = makeLegacyMap('SEQUENCE');
|
|
155
|
-
channelKeyToSeqAck.init(channelKey, seqToAck);
|
|
156
|
-
|
|
61
|
+
const makeIBCConnectionHandler = zone.exoClass(
|
|
62
|
+
'IBCConnectionHandler',
|
|
63
|
+
undefined,
|
|
157
64
|
/**
|
|
158
|
-
* @param {
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
65
|
+
* @param {{
|
|
66
|
+
* protocolUtils: any;
|
|
67
|
+
* channelKeyToConnP: MapStore<
|
|
68
|
+
* string,
|
|
69
|
+
* import('@agoric/vow').Remote<Connection>
|
|
70
|
+
* >;
|
|
71
|
+
* channelKeyToSeqAck: MapStore<
|
|
72
|
+
* string,
|
|
73
|
+
* MapStore<number, import('@agoric/vow').VowKit<Bytes>>
|
|
74
|
+
* >;
|
|
75
|
+
* }} param0
|
|
76
|
+
* @param {{
|
|
77
|
+
* channelID: IBCChannelID;
|
|
78
|
+
* portID: string;
|
|
79
|
+
* rChannelID: IBCChannelID;
|
|
80
|
+
* rPortID: string;
|
|
81
|
+
* order: 'ORDERED' | 'UNORDERED';
|
|
82
|
+
* }} param1
|
|
164
83
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
_handler,
|
|
169
|
-
{ relativeTimeoutNs } = {},
|
|
84
|
+
(
|
|
85
|
+
{ protocolUtils, channelKeyToConnP, channelKeyToSeqAck },
|
|
86
|
+
{ channelID, portID, rChannelID, rPortID, order },
|
|
170
87
|
) => {
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
source_channel: channelID,
|
|
175
|
-
destination_port: rPortID,
|
|
176
|
-
destination_channel: rChannelID,
|
|
177
|
-
data: dataToBase64(packetBytes),
|
|
178
|
-
};
|
|
179
|
-
return ibcSendPacket(packet, seqToAck, relativeTimeoutNs);
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
if (order === 'ORDERED') {
|
|
183
|
-
// We set up a queue on the receiver to enforce ordering.
|
|
184
|
-
const withChannelReceiveQueue = makeWithQueue();
|
|
185
|
-
onReceive = withChannelReceiveQueue(onReceive);
|
|
186
|
-
}
|
|
88
|
+
const channelKey = `${channelID}:${portID}`;
|
|
89
|
+
const seqToAck = zone.detached().mapStore('seqToAck');
|
|
90
|
+
channelKeyToSeqAck.init(channelKey, seqToAck);
|
|
187
91
|
|
|
188
|
-
|
|
92
|
+
return {
|
|
93
|
+
protocolUtils,
|
|
94
|
+
channelID,
|
|
95
|
+
portID,
|
|
96
|
+
rChannelID,
|
|
97
|
+
rPortID,
|
|
98
|
+
order,
|
|
99
|
+
channelKeyToConnP,
|
|
100
|
+
channelKeyToSeqAck,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
/** @type {Required<ConnectionHandler>['onOpen']} */
|
|
189
105
|
async onOpen(conn, localAddr, remoteAddr, _handler) {
|
|
106
|
+
const { channelID, portID, channelKeyToConnP } = this.state;
|
|
107
|
+
|
|
190
108
|
console.debug(
|
|
191
109
|
'onOpen Remote IBC Connection',
|
|
192
110
|
channelID,
|
|
@@ -194,194 +112,615 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
|
|
|
194
112
|
localAddr,
|
|
195
113
|
remoteAddr,
|
|
196
114
|
);
|
|
197
|
-
const
|
|
198
|
-
|
|
115
|
+
const channelKey = `${channelID}:${portID}`;
|
|
116
|
+
|
|
117
|
+
channelKeyToConnP.init(channelKey, conn);
|
|
199
118
|
},
|
|
200
|
-
onReceive
|
|
201
|
-
async
|
|
119
|
+
/** @type {Required<ConnectionHandler>['onReceive']} */
|
|
120
|
+
async onReceive(
|
|
121
|
+
_conn,
|
|
122
|
+
packetBytes,
|
|
123
|
+
_handler,
|
|
124
|
+
{ relativeTimeoutNs } = {},
|
|
125
|
+
) {
|
|
126
|
+
const { portID, channelID, rPortID, rChannelID } = this.state;
|
|
127
|
+
const { protocolUtils } = this.state;
|
|
128
|
+
// console.error(`Remote IBC Handler ${portID} ${channelID}`);
|
|
129
|
+
/** @type {IBCPacket} */
|
|
202
130
|
const packet = {
|
|
203
131
|
source_port: portID,
|
|
204
132
|
source_channel: channelID,
|
|
133
|
+
destination_port: rPortID,
|
|
134
|
+
destination_channel: rChannelID,
|
|
135
|
+
data: byteSourceToBase64(packetBytes),
|
|
205
136
|
};
|
|
206
|
-
|
|
137
|
+
return protocolUtils.ibcSendPacket(packet, relativeTimeoutNs);
|
|
138
|
+
},
|
|
139
|
+
/** @type {Required<ConnectionHandler>['onClose']} */
|
|
140
|
+
async onClose() {
|
|
141
|
+
const { portID, channelID } = this.state;
|
|
142
|
+
const { protocolUtils, channelKeyToSeqAck } = this.state;
|
|
143
|
+
|
|
144
|
+
const packet = {
|
|
145
|
+
source_port: portID,
|
|
146
|
+
source_channel: channelID,
|
|
147
|
+
};
|
|
148
|
+
await protocolUtils.downcall('startChannelCloseInit', {
|
|
149
|
+
packet,
|
|
150
|
+
});
|
|
207
151
|
const rejectReason = Error('Connection closed');
|
|
208
|
-
|
|
209
|
-
|
|
152
|
+
const channelKey = `${channelID}:${portID}`;
|
|
153
|
+
|
|
154
|
+
const seqToAck = channelKeyToSeqAck.get(channelKey);
|
|
155
|
+
|
|
156
|
+
for (const ackKit of seqToAck.values()) {
|
|
157
|
+
ackKit.resolver.reject(rejectReason);
|
|
210
158
|
}
|
|
211
159
|
channelKeyToSeqAck.delete(channelKey);
|
|
212
160
|
},
|
|
213
|
-
}
|
|
214
|
-
|
|
161
|
+
},
|
|
162
|
+
);
|
|
215
163
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
*/
|
|
219
|
-
const localAddrToPortID = localAddr => {
|
|
220
|
-
const m = localAddr.match(/^\/ibc-port\/([-a-zA-Z0-9._+#[\]<>]+)$/);
|
|
221
|
-
if (!m) {
|
|
222
|
-
throw TypeError(
|
|
223
|
-
`Invalid port specification ${localAddr}; expected "/ibc-port/PORT"`,
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
return m[1];
|
|
227
|
-
};
|
|
164
|
+
return makeIBCConnectionHandler;
|
|
165
|
+
};
|
|
228
166
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
167
|
+
/**
|
|
168
|
+
* @param {Zone} zone
|
|
169
|
+
* @param {VowTools} powers
|
|
170
|
+
*/
|
|
171
|
+
export const prepareIBCProtocol = (zone, powers) => {
|
|
172
|
+
const { makeVowKit, watch } = powers;
|
|
173
|
+
|
|
174
|
+
const makeIBCConnectionHandler = prepareIBCConnectionHandler(zone);
|
|
233
175
|
|
|
234
176
|
/**
|
|
235
|
-
* @typedef {object}
|
|
236
|
-
* @property {
|
|
237
|
-
* @property {'ORDERED'|'UNORDERED'} order
|
|
238
|
-
* @property {string} version
|
|
239
|
-
* @property {IBCPacket} packet
|
|
240
|
-
* @property {PromiseRecord<ConnectionHandler>} deferredHandler
|
|
177
|
+
* @typedef {object} IBCDevice
|
|
178
|
+
* @property {(method: string, args: object) => Promise<any>} downcall
|
|
241
179
|
*/
|
|
242
180
|
|
|
243
181
|
/**
|
|
244
|
-
* @type {
|
|
182
|
+
* @type {WeakMapStore<
|
|
183
|
+
* IBCDevice,
|
|
184
|
+
* {
|
|
185
|
+
* protocolHandler: ProtocolHandler;
|
|
186
|
+
* bridgeHandler: BridgeHandler;
|
|
187
|
+
* }
|
|
188
|
+
* >} Map
|
|
189
|
+
* from IBC device to existing handler
|
|
245
190
|
*/
|
|
246
|
-
|
|
247
|
-
|
|
191
|
+
const ibcdevToKit = zone.weakMapStore('ibcdevToHandler');
|
|
192
|
+
|
|
193
|
+
const detached = zone.detached();
|
|
248
194
|
|
|
249
195
|
/**
|
|
250
|
-
*
|
|
196
|
+
* Create a handler for the IBC protocol, both from the network and from the
|
|
197
|
+
* bridge.
|
|
251
198
|
*/
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
199
|
+
const makeIBCProtocolKit = zone.exoClassKit(
|
|
200
|
+
'IBCProtocolHandler',
|
|
201
|
+
undefined,
|
|
202
|
+
/** @param {IBCDevice} ibcdev */
|
|
203
|
+
ibcdev => {
|
|
204
|
+
/** @type {MapStore<string, Remote<Connection>>} */
|
|
205
|
+
const channelKeyToConnP = detached.mapStore('channelKeyToConnP');
|
|
206
|
+
|
|
207
|
+
/** @type {MapStore<string, ConnectingInfo>} */
|
|
208
|
+
const channelKeyToInfo = detached.mapStore('channelKeyToInfo');
|
|
209
|
+
|
|
210
|
+
/** @type {MapStore<string, Remote<InboundAttempt>>} */
|
|
211
|
+
const channelKeyToAttempt = detached.mapStore('channelKeyToAttempt');
|
|
212
|
+
|
|
213
|
+
/** @type {MapStore<string, Outbound[]>} */
|
|
214
|
+
const srcPortToOutbounds = detached.mapStore('srcPortToOutbounds');
|
|
215
|
+
|
|
216
|
+
/** @type {MapStore<string, MapStore<number, VowKit<Bytes>>>} */
|
|
217
|
+
const channelKeyToSeqAck = detached.mapStore('channelKeyToSeqAck');
|
|
218
|
+
|
|
219
|
+
/** @type {MapStore<string, SetStore<VowResolver>>} */
|
|
220
|
+
const portToPendingConns = detached.mapStore('portToPendingConns');
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
ibcdev,
|
|
224
|
+
channelKeyToConnP,
|
|
225
|
+
channelKeyToInfo,
|
|
226
|
+
channelKeyToAttempt,
|
|
227
|
+
srcPortToOutbounds,
|
|
228
|
+
channelKeyToSeqAck,
|
|
229
|
+
portToPendingConns,
|
|
230
|
+
lastPortID: 0n, // Nonce for creating port identifiers.
|
|
231
|
+
/** @type {Remote<ProtocolImpl> | null} */
|
|
232
|
+
protocolImpl: null,
|
|
270
233
|
};
|
|
271
|
-
return callIBCDevice('bindPort', { packet });
|
|
272
234
|
},
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
235
|
+
{
|
|
236
|
+
protocolHandler: {
|
|
237
|
+
/** @type {Required<ProtocolHandler>['onCreate']} */
|
|
238
|
+
async onCreate(impl) {
|
|
239
|
+
console.debug('IBC onCreate');
|
|
240
|
+
this.state.protocolImpl = impl;
|
|
241
|
+
},
|
|
242
|
+
/** @type {Required<ProtocolHandler>['onInstantiate']} */
|
|
243
|
+
async onInstantiate() {
|
|
244
|
+
// The IBC channel is not known until after handshake.
|
|
245
|
+
return '';
|
|
246
|
+
},
|
|
247
|
+
/** @type {Required<ProtocolHandler>['generatePortID']} */
|
|
248
|
+
async generatePortID() {
|
|
249
|
+
this.state.lastPortID += 1n;
|
|
250
|
+
return `port-${this.state.lastPortID}`;
|
|
251
|
+
},
|
|
252
|
+
/** @type {Required<ProtocolHandler>['onBind']} */
|
|
253
|
+
async onBind(_port, localAddr) {
|
|
254
|
+
const { util } = this.facets;
|
|
255
|
+
const { portToPendingConns } = this.state;
|
|
256
|
+
|
|
257
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
258
|
+
const portID = localAddrToPortID(localAddr);
|
|
259
|
+
portToPendingConns.init(portID, detached.setStore('pendingConns'));
|
|
260
|
+
const packet = {
|
|
261
|
+
source_port: portID,
|
|
262
|
+
};
|
|
263
|
+
return util.downcall('bindPort', { packet });
|
|
264
|
+
},
|
|
265
|
+
/** @type {Required<ProtocolHandler>['onConnect']} */
|
|
266
|
+
async onConnect(_port, localAddr, remoteAddr) {
|
|
267
|
+
const { util } = this.facets;
|
|
268
|
+
const { portToPendingConns, srcPortToOutbounds } = this.state;
|
|
269
|
+
|
|
270
|
+
console.debug('IBC onConnect', localAddr, remoteAddr);
|
|
271
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
272
|
+
const portID = localAddrToPortID(localAddr);
|
|
273
|
+
const pendingConns = portToPendingConns.get(portID);
|
|
274
|
+
|
|
275
|
+
const { rPortID, hops, order, version } =
|
|
276
|
+
decodeRemoteIbcAddress(remoteAddr);
|
|
277
|
+
|
|
278
|
+
const kit = makeVowKit();
|
|
279
|
+
|
|
280
|
+
pendingConns.add(kit.resolver);
|
|
281
|
+
/** @type {Outbound} */
|
|
282
|
+
const ob = {
|
|
283
|
+
portID,
|
|
284
|
+
counterparty: { port_id: rPortID },
|
|
285
|
+
connectionHops: hops,
|
|
286
|
+
order,
|
|
287
|
+
version,
|
|
288
|
+
onConnectP: kit,
|
|
289
|
+
localAddr,
|
|
290
|
+
};
|
|
291
|
+
if (srcPortToOutbounds.has(portID)) {
|
|
292
|
+
const outbounds = srcPortToOutbounds.get(portID);
|
|
293
|
+
srcPortToOutbounds.set(portID, harden([...outbounds, ob]));
|
|
294
|
+
} else {
|
|
295
|
+
srcPortToOutbounds.init(portID, harden([ob]));
|
|
296
|
+
}
|
|
331
297
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
298
|
+
// Initialise the channel, which a listening relayer should pick up.
|
|
299
|
+
/** @type {IBCDowncallPacket<'startChannelOpenInit'>} */
|
|
300
|
+
const packet = {
|
|
301
|
+
source_port: portID,
|
|
302
|
+
destination_port: rPortID,
|
|
303
|
+
};
|
|
338
304
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
305
|
+
await util.downcall('startChannelOpenInit', {
|
|
306
|
+
packet,
|
|
307
|
+
order,
|
|
308
|
+
hops,
|
|
309
|
+
version,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
return kit.vow;
|
|
313
|
+
},
|
|
314
|
+
/** @type {Required<ProtocolHandler>['onListen']} */
|
|
315
|
+
async onListen(_port, localAddr) {
|
|
316
|
+
console.debug('IBC onListen', localAddr);
|
|
317
|
+
},
|
|
318
|
+
/** @type {Required<ProtocolHandler>['onListenRemove']} */
|
|
319
|
+
async onListenRemove(_port, localAddr) {
|
|
320
|
+
console.debug('IBC onListenRemove', localAddr);
|
|
321
|
+
},
|
|
322
|
+
/** @type {Required<ProtocolHandler>['onRevoke']} */
|
|
323
|
+
async onRevoke(_port, localAddr) {
|
|
324
|
+
const { portToPendingConns } = this.state;
|
|
325
|
+
console.debug('IBC onRevoke', localAddr);
|
|
326
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
327
|
+
const portID = localAddrToPortID(localAddr);
|
|
328
|
+
|
|
329
|
+
const pendingConns = portToPendingConns.get(portID);
|
|
330
|
+
portToPendingConns.delete(portID);
|
|
331
|
+
const revoked = Error(`Port ${localAddr} revoked`);
|
|
332
|
+
for (const resolver of pendingConns.values()) {
|
|
333
|
+
resolver.reject(revoked);
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
bridgeHandler: {
|
|
338
|
+
/** @param {IBCEvent<IBCBridgeEvent>} obj */
|
|
339
|
+
async fromBridge(obj) {
|
|
340
|
+
const {
|
|
341
|
+
protocolImpl,
|
|
342
|
+
channelKeyToAttempt,
|
|
343
|
+
channelKeyToInfo,
|
|
344
|
+
srcPortToOutbounds,
|
|
345
|
+
channelKeyToConnP,
|
|
346
|
+
channelKeyToSeqAck,
|
|
347
|
+
} = this.state;
|
|
348
|
+
|
|
349
|
+
const { util } = this.facets;
|
|
350
|
+
|
|
351
|
+
console.info('IBC fromBridge', obj);
|
|
352
|
+
await null;
|
|
353
|
+
switch (obj.event) {
|
|
354
|
+
case 'channelOpenInit': {
|
|
355
|
+
const {
|
|
356
|
+
channelID,
|
|
357
|
+
portID,
|
|
358
|
+
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
359
|
+
connectionHops: hops,
|
|
360
|
+
order,
|
|
361
|
+
version,
|
|
362
|
+
asyncVersions,
|
|
363
|
+
} = /** @type {IBCEvent<'channelOpenInit'>} */ (obj);
|
|
364
|
+
if (!asyncVersions) {
|
|
365
|
+
// Synchronous versions have already been negotiated.
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// We have async version negotiation, so we must call back before the
|
|
370
|
+
// channel can make progress.
|
|
371
|
+
// We just use the provided version without failing.
|
|
372
|
+
await util.downcall('initOpenExecuted', {
|
|
373
|
+
packet: {
|
|
374
|
+
source_port: portID,
|
|
375
|
+
source_channel: channelID,
|
|
376
|
+
destination_port: rPortID,
|
|
377
|
+
destination_channel: rChannelID,
|
|
378
|
+
},
|
|
379
|
+
order,
|
|
380
|
+
version,
|
|
381
|
+
hops,
|
|
382
|
+
});
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
case 'channelOpenTry': {
|
|
386
|
+
// They're (more or less politely) asking if we are listening, so make an attempt.
|
|
387
|
+
const {
|
|
388
|
+
portID,
|
|
389
|
+
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
390
|
+
connectionHops: hops,
|
|
391
|
+
order,
|
|
392
|
+
version,
|
|
393
|
+
counterpartyVersion: rVersion,
|
|
394
|
+
} = /** @type {IBCEvent<'channelOpenTry'>} */ (obj);
|
|
395
|
+
|
|
396
|
+
const localAddr = encodeLocalIbcAddress(portID, order, version);
|
|
397
|
+
const remoteAddr = encodeRemoteIbcAddress(
|
|
398
|
+
hops,
|
|
399
|
+
rPortID,
|
|
400
|
+
order,
|
|
401
|
+
rVersion,
|
|
402
|
+
rChannelID,
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
// See if we allow an inbound attempt for this address pair (without
|
|
406
|
+
// rejecting).
|
|
407
|
+
// const attempt = await this.state.protocolImpl
|
|
408
|
+
// ?.inbound(localAddr, remoteAddr)
|
|
409
|
+
// .then(
|
|
410
|
+
// ack => console.info('Manual packet', ack, 'acked:', ack),
|
|
411
|
+
// e => console.warn('Manual packet', e, 'failed:', e),
|
|
412
|
+
// );
|
|
413
|
+
|
|
414
|
+
assert(protocolImpl);
|
|
415
|
+
|
|
416
|
+
return watch(
|
|
417
|
+
E(protocolImpl).inbound(localAddr, remoteAddr),
|
|
418
|
+
this.facets.protocolImplInboundWatcher,
|
|
419
|
+
{
|
|
420
|
+
obj,
|
|
421
|
+
rPortID,
|
|
422
|
+
rChannelID,
|
|
423
|
+
hops,
|
|
424
|
+
},
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
case 'channelOpenAck': {
|
|
429
|
+
// Complete the pending outbound connection.
|
|
430
|
+
const {
|
|
431
|
+
portID,
|
|
432
|
+
channelID,
|
|
433
|
+
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
434
|
+
counterpartyVersion: rVersion,
|
|
435
|
+
connectionHops: rHops,
|
|
436
|
+
} = /** @type {IBCEvent<'channelOpenAck'>} */ (obj);
|
|
437
|
+
|
|
438
|
+
const outbounds = this.state.srcPortToOutbounds.has(portID)
|
|
439
|
+
? [...this.state.srcPortToOutbounds.get(portID)]
|
|
440
|
+
: [];
|
|
441
|
+
const oidx = outbounds.findIndex(
|
|
442
|
+
({
|
|
443
|
+
counterparty: { port_id: iPortID },
|
|
444
|
+
connectionHops: iHops,
|
|
445
|
+
}) => {
|
|
446
|
+
if (iPortID !== rPortID) {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
if (iHops.length !== rHops.length) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
for (let i = 0; i < iHops.length; i += 1) {
|
|
453
|
+
if (iHops[i] !== rHops[i]) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return true;
|
|
458
|
+
},
|
|
459
|
+
);
|
|
460
|
+
oidx >= 0 || Fail`${portID}: did not expect channelOpenAck`;
|
|
461
|
+
const { onConnectP, localAddr, ...chanInfo } = outbounds[oidx];
|
|
462
|
+
outbounds.splice(oidx, 1);
|
|
463
|
+
if (outbounds.length === 0) {
|
|
464
|
+
srcPortToOutbounds.delete(portID);
|
|
465
|
+
} else {
|
|
466
|
+
srcPortToOutbounds.set(portID, harden(outbounds));
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Finish the outbound connection.
|
|
470
|
+
const remoteAddress = encodeRemoteIbcAddress(
|
|
471
|
+
rHops,
|
|
472
|
+
rPortID,
|
|
473
|
+
chanInfo.order,
|
|
474
|
+
rVersion,
|
|
475
|
+
rChannelID,
|
|
476
|
+
);
|
|
477
|
+
const localAddress = `${localAddr}/${chanInfo.order.toLowerCase()}/${rVersion}/ibc-channel/${channelID}`;
|
|
478
|
+
const rchandler = makeIBCConnectionHandler(
|
|
479
|
+
{
|
|
480
|
+
protocolUtils: util,
|
|
481
|
+
channelKeyToConnP,
|
|
482
|
+
channelKeyToSeqAck,
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
channelID,
|
|
486
|
+
portID,
|
|
487
|
+
rChannelID,
|
|
488
|
+
rPortID,
|
|
489
|
+
order: chanInfo.order,
|
|
490
|
+
},
|
|
491
|
+
);
|
|
492
|
+
onConnectP.resolver.resolve({
|
|
493
|
+
localAddress,
|
|
494
|
+
remoteAddress,
|
|
495
|
+
handler: rchandler,
|
|
496
|
+
});
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
case 'channelOpenConfirm': {
|
|
501
|
+
const { portID, channelID } =
|
|
502
|
+
/** @type {IBCEvent<'channelOpenConfirm'>} */ (obj);
|
|
503
|
+
|
|
504
|
+
const channelKey = `${channelID}:${portID}`;
|
|
505
|
+
channelKeyToAttempt.has(channelKey) ||
|
|
506
|
+
Fail`${channelKey}: did not expect channelOpenConfirm`;
|
|
507
|
+
const attemptP = channelKeyToAttempt.get(channelKey);
|
|
508
|
+
channelKeyToAttempt.delete(channelKey);
|
|
509
|
+
|
|
510
|
+
// We have the information from our inbound connection, so complete it.
|
|
511
|
+
const {
|
|
512
|
+
order,
|
|
513
|
+
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
514
|
+
} = channelKeyToInfo.get(channelKey);
|
|
515
|
+
channelKeyToInfo.delete(channelKey);
|
|
516
|
+
|
|
517
|
+
// Accept the attempt.
|
|
518
|
+
const rchandler = makeIBCConnectionHandler(
|
|
519
|
+
{
|
|
520
|
+
protocolUtils: util,
|
|
521
|
+
channelKeyToConnP,
|
|
522
|
+
channelKeyToSeqAck,
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
channelID,
|
|
526
|
+
portID,
|
|
527
|
+
rChannelID,
|
|
528
|
+
rPortID,
|
|
529
|
+
order,
|
|
530
|
+
},
|
|
531
|
+
);
|
|
532
|
+
const localAddr = await E(attemptP).getLocalAddress();
|
|
533
|
+
void E(attemptP).accept({
|
|
534
|
+
localAddress: `${localAddr}/ibc-channel/${channelID}`,
|
|
535
|
+
handler: rchandler,
|
|
536
|
+
});
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
case 'receivePacket': {
|
|
541
|
+
const { packet } = /** @type {IBCEvent<'receivePacket'>} */ (obj);
|
|
542
|
+
const {
|
|
543
|
+
data: data64,
|
|
544
|
+
destination_port: portID,
|
|
545
|
+
destination_channel: channelID,
|
|
546
|
+
} = packet;
|
|
547
|
+
const channelKey = `${channelID}:${portID}`;
|
|
548
|
+
const conn = channelKeyToConnP.get(channelKey);
|
|
549
|
+
const data = base64ToBytes(data64);
|
|
550
|
+
|
|
551
|
+
return watch(E(conn).send(data), this.facets.ackWatcher, {
|
|
552
|
+
packet,
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
case 'acknowledgementPacket': {
|
|
557
|
+
const { packet, acknowledgement } =
|
|
558
|
+
/** @type {IBCEvent<'acknowledgementPacket'>} */ (obj);
|
|
559
|
+
const {
|
|
560
|
+
sequence,
|
|
561
|
+
source_channel: channelID,
|
|
562
|
+
source_port: portID,
|
|
563
|
+
} = packet;
|
|
564
|
+
if (sequence === undefined)
|
|
565
|
+
throw TypeError('acknowledgementPacket without sequence');
|
|
566
|
+
const ackKit = util.findAckKit(channelID, portID, sequence);
|
|
567
|
+
ackKit.resolver.resolve(base64ToBytes(acknowledgement));
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
case 'timeoutPacket': {
|
|
572
|
+
const { packet } = /** @type {IBCEvent<'timeoutPacket'>} */ (obj);
|
|
573
|
+
const {
|
|
574
|
+
sequence,
|
|
575
|
+
source_channel: channelID,
|
|
576
|
+
source_port: portID,
|
|
577
|
+
} = packet;
|
|
578
|
+
if (sequence === undefined)
|
|
579
|
+
throw TypeError('timeoutPacket without sequence');
|
|
580
|
+
|
|
581
|
+
const ackKit = util.findAckKit(channelID, portID, sequence);
|
|
582
|
+
ackKit.resolver.reject(Error(`Packet timed out`));
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
case 'channelCloseInit':
|
|
587
|
+
case 'channelCloseConfirm': {
|
|
588
|
+
const { portID, channelID } =
|
|
589
|
+
// could be either but that complicates line wrapping
|
|
590
|
+
/** @type {IBCEvent<'channelCloseInit'>} */ (obj);
|
|
591
|
+
const channelKey = `${channelID}:${portID}`;
|
|
592
|
+
if (channelKeyToConnP.has(channelKey)) {
|
|
593
|
+
const conn = channelKeyToConnP.get(channelKey);
|
|
594
|
+
channelKeyToConnP.delete(channelKey);
|
|
595
|
+
void E(conn).close();
|
|
596
|
+
}
|
|
597
|
+
break;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
case 'sendPacket': {
|
|
601
|
+
const { packet, relativeTimeoutNs } =
|
|
602
|
+
/** @type {IBCEvent<'sendPacket'>} */ (obj);
|
|
603
|
+
util.ibcSendPacket(packet, relativeTimeoutNs).then(
|
|
604
|
+
ack => console.info('Manual packet', packet, 'acked:', ack),
|
|
605
|
+
e => console.warn('Manual packet', packet, 'failed:', e),
|
|
606
|
+
);
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
default:
|
|
611
|
+
console.error('Unexpected IBC_EVENT', obj.event);
|
|
612
|
+
assert.fail(X`unrecognized method ${obj.event}`, TypeError);
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
util: {
|
|
617
|
+
/**
|
|
618
|
+
* @template {IBCDowncallMethod} M
|
|
619
|
+
* @param {M} method
|
|
620
|
+
* @param {IBCDowncall<M>} args
|
|
621
|
+
*/
|
|
622
|
+
downcall(method, args) {
|
|
623
|
+
return E(this.state.ibcdev).downcall(method, args);
|
|
624
|
+
},
|
|
625
|
+
/**
|
|
626
|
+
* Send a packet out via the IBC device.
|
|
627
|
+
*
|
|
628
|
+
* @param {IBCPacket} packet
|
|
629
|
+
* @param {bigint} [relativeTimeoutNs]
|
|
630
|
+
* @returns {PromiseVow<Bytes>} Acknowledgement data
|
|
631
|
+
*/
|
|
632
|
+
async ibcSendPacket(
|
|
633
|
+
packet,
|
|
634
|
+
relativeTimeoutNs = DEFAULT_PACKET_TIMEOUT_NS,
|
|
635
|
+
) {
|
|
636
|
+
const { util } = this.facets;
|
|
637
|
+
// Make a kernel call to do the send.
|
|
638
|
+
const fullPacket = await util.downcall('sendPacket', {
|
|
639
|
+
packet,
|
|
640
|
+
relativeTimeoutNs,
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
// Extract the actual sequence number from the return.
|
|
644
|
+
const {
|
|
645
|
+
sequence,
|
|
646
|
+
source_channel: channelID,
|
|
647
|
+
source_port: portID,
|
|
648
|
+
} = fullPacket;
|
|
649
|
+
|
|
650
|
+
/** @type {VowKit<Bytes>} */
|
|
651
|
+
const { vow } = util.findAckKit(channelID, portID, sequence);
|
|
652
|
+
return vow;
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* @param {IBCChannelID} channelID
|
|
657
|
+
* @param {IBCPortID} portID
|
|
658
|
+
* @param {number} sequence
|
|
659
|
+
*/
|
|
660
|
+
findAckKit(channelID, portID, sequence) {
|
|
661
|
+
const { channelKeyToSeqAck } = this.state;
|
|
662
|
+
const channelKey = `${channelID}:${portID}`;
|
|
663
|
+
const seqToAck = channelKeyToSeqAck.get(channelKey);
|
|
664
|
+
if (seqToAck.has(sequence)) {
|
|
665
|
+
return seqToAck.get(sequence);
|
|
666
|
+
}
|
|
667
|
+
const kit = makeVowKit();
|
|
668
|
+
seqToAck.init(sequence, kit);
|
|
669
|
+
return kit;
|
|
670
|
+
},
|
|
671
|
+
},
|
|
672
|
+
ackWatcher: {
|
|
673
|
+
/**
|
|
674
|
+
* @param {string} ack
|
|
675
|
+
* @param {{ packet: any }} watcherContext
|
|
676
|
+
*/
|
|
677
|
+
onFulfilled(ack, watcherContext) {
|
|
678
|
+
const { packet } = watcherContext;
|
|
679
|
+
|
|
680
|
+
const realAck = ack || DEFAULT_ACKNOWLEDGEMENT;
|
|
681
|
+
const ack64 = byteSourceToBase64(realAck);
|
|
682
|
+
this.facets.util
|
|
683
|
+
.downcall('receiveExecuted', {
|
|
684
|
+
packet,
|
|
685
|
+
ack: ack64,
|
|
686
|
+
})
|
|
687
|
+
.catch(e => this.facets.ackWatcher.onRejected(e));
|
|
688
|
+
},
|
|
689
|
+
onRejected(e) {
|
|
690
|
+
console.log(e);
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
protocolImplAttemptWatcher: {
|
|
694
|
+
/**
|
|
695
|
+
* @param {string} attemptedLocal
|
|
696
|
+
* @param {{
|
|
697
|
+
* channelID: IBCChannelID;
|
|
698
|
+
* portID: string;
|
|
699
|
+
* attempt: any;
|
|
700
|
+
* obj: any;
|
|
701
|
+
* asyncVersions: any;
|
|
702
|
+
* rPortID: string;
|
|
703
|
+
* rChannelID: IBCChannelID;
|
|
704
|
+
* order: IBCChannelOrdering;
|
|
705
|
+
* hops: any;
|
|
706
|
+
* version: string;
|
|
707
|
+
* }} watcherContext
|
|
708
|
+
*/
|
|
709
|
+
onFulfilled(attemptedLocal, watcherContext) {
|
|
365
710
|
const {
|
|
366
711
|
channelID,
|
|
367
712
|
portID,
|
|
368
|
-
|
|
369
|
-
|
|
713
|
+
attempt,
|
|
714
|
+
obj,
|
|
715
|
+
asyncVersions,
|
|
716
|
+
rPortID,
|
|
717
|
+
rChannelID,
|
|
370
718
|
order,
|
|
719
|
+
hops,
|
|
371
720
|
version,
|
|
372
|
-
|
|
373
|
-
} =
|
|
374
|
-
|
|
375
|
-
const localAddr = `/ibc-port/${portID}/${order.toLowerCase()}/${version}`;
|
|
376
|
-
const ibcHops = hops.map(hop => `/ibc-hop/${hop}`).join('/');
|
|
377
|
-
const remoteAddr = `${ibcHops}/ibc-port/${rPortID}/${order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`;
|
|
378
|
-
|
|
379
|
-
// See if we allow an inbound attempt for this address pair (without
|
|
380
|
-
// rejecting).
|
|
381
|
-
const attemptP = E(protocolImpl).inbound(localAddr, remoteAddr);
|
|
721
|
+
} = watcherContext;
|
|
722
|
+
const { channelKeyToAttempt, channelKeyToInfo } = this.state;
|
|
382
723
|
|
|
383
|
-
// Tell what version string we negotiated.
|
|
384
|
-
const attemptedLocal = await E(attemptP).getLocalAddress();
|
|
385
724
|
const match = attemptedLocal.match(
|
|
386
725
|
// Match: ... /ORDER/VERSION ...
|
|
387
726
|
new RegExp('^(/[^/]+/[^/]+)*/(ordered|unordered)/([^/]+)(/|$)'),
|
|
@@ -393,193 +732,103 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) {
|
|
|
393
732
|
`${channelKey}: cannot determine version from attempted local address ${attemptedLocal}`,
|
|
394
733
|
);
|
|
395
734
|
}
|
|
396
|
-
const negotiatedVersion = match[3];
|
|
397
735
|
|
|
398
|
-
|
|
736
|
+
channelKeyToAttempt.init(channelKey, attempt);
|
|
399
737
|
channelKeyToInfo.init(channelKey, obj);
|
|
400
738
|
|
|
739
|
+
const negotiatedVersion = match[3];
|
|
740
|
+
|
|
401
741
|
try {
|
|
402
|
-
if (
|
|
403
|
-
//
|
|
742
|
+
if (asyncVersions) {
|
|
743
|
+
// We have async version negotiation, so we must call back now.
|
|
744
|
+
return this.facets.util.downcall('tryOpenExecuted', {
|
|
745
|
+
packet: {
|
|
746
|
+
source_port: rPortID,
|
|
747
|
+
source_channel: rChannelID,
|
|
748
|
+
destination_port: portID,
|
|
749
|
+
destination_channel: channelID,
|
|
750
|
+
},
|
|
751
|
+
order,
|
|
752
|
+
version: negotiatedVersion,
|
|
753
|
+
hops,
|
|
754
|
+
});
|
|
755
|
+
} else if (negotiatedVersion !== version) {
|
|
756
|
+
// Too late; the other side gave us a version we didn't like.
|
|
404
757
|
throw Error(
|
|
405
|
-
`${channelKey}: negotiated version was ${negotiatedVersion}
|
|
758
|
+
`${channelKey}: async negotiated version was ${negotiatedVersion} but synchronous version was ${version}`,
|
|
406
759
|
);
|
|
407
760
|
}
|
|
408
761
|
} catch (e) {
|
|
409
762
|
// Clean up after our failed attempt.
|
|
410
|
-
|
|
763
|
+
channelKeyToAttempt.delete(channelKey);
|
|
411
764
|
channelKeyToInfo.delete(channelKey);
|
|
412
|
-
void E(
|
|
765
|
+
void E(attempt).close();
|
|
413
766
|
throw e;
|
|
414
767
|
}
|
|
415
|
-
|
|
416
|
-
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
protocolImplInboundWatcher: {
|
|
771
|
+
/**
|
|
772
|
+
* @param {any} attempt
|
|
773
|
+
* @param {Record<string, any>} watchContext
|
|
774
|
+
*/
|
|
775
|
+
onFulfilled(attempt, watchContext) {
|
|
776
|
+
const { obj } = watchContext;
|
|
417
777
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
} = obj;
|
|
427
|
-
const outbounds = srcPortToOutbounds.has(portID)
|
|
428
|
-
? srcPortToOutbounds.get(portID)
|
|
429
|
-
: [];
|
|
430
|
-
const oidx = outbounds.findIndex(
|
|
431
|
-
({ counterparty: { port_id: iPortID }, connectionHops: iHops }) => {
|
|
432
|
-
if (iPortID !== rPortID) {
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
if (iHops.length !== rHops.length) {
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
for (let i = 0; i < iHops.length; i += 1) {
|
|
439
|
-
if (iHops[i] !== rHops[i]) {
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return true;
|
|
778
|
+
// Tell what version string we negotiated.
|
|
779
|
+
return watch(
|
|
780
|
+
E(attempt).getLocalAddress(),
|
|
781
|
+
this.facets.protocolImplAttemptWatcher,
|
|
782
|
+
{
|
|
783
|
+
...obj,
|
|
784
|
+
...watchContext,
|
|
785
|
+
attempt,
|
|
444
786
|
},
|
|
445
787
|
);
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
srcPortToOutbounds.delete(portID);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Finish the outbound connection.
|
|
454
|
-
const ibcHops = rHops.map(hop => `/ibc-hop/${hop}`).join('/');
|
|
455
|
-
const remoteAddress = `${ibcHops}/ibc-port/${rPortID}/${chanInfo.order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`;
|
|
456
|
-
const localAddress = `${localAddr}/ibc-channel/${channelID}`;
|
|
457
|
-
const rchandler = makeIBCConnectionHandler(
|
|
458
|
-
channelID,
|
|
459
|
-
portID,
|
|
460
|
-
rChannelID,
|
|
461
|
-
rPortID,
|
|
462
|
-
chanInfo.order,
|
|
463
|
-
);
|
|
464
|
-
onConnectP.resolve({
|
|
465
|
-
localAddress,
|
|
466
|
-
remoteAddress,
|
|
467
|
-
handler: rchandler,
|
|
468
|
-
});
|
|
469
|
-
break;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
case 'channelOpenConfirm': {
|
|
473
|
-
const { portID, channelID } = obj;
|
|
474
|
-
const channelKey = `${channelID}:${portID}`;
|
|
475
|
-
channelKeyToAttemptP.has(channelKey) ||
|
|
476
|
-
Fail`${channelKey}: did not expect channelOpenConfirm`;
|
|
477
|
-
const attemptP = channelKeyToAttemptP.get(channelKey);
|
|
478
|
-
channelKeyToAttemptP.delete(channelKey);
|
|
479
|
-
|
|
480
|
-
// We have the information from our inbound connection, so complete it.
|
|
481
|
-
const {
|
|
482
|
-
order,
|
|
483
|
-
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
484
|
-
} = channelKeyToInfo.get(channelKey);
|
|
485
|
-
channelKeyToInfo.delete(channelKey);
|
|
486
|
-
|
|
487
|
-
// Accept the attempt.
|
|
488
|
-
const rchandler = makeIBCConnectionHandler(
|
|
489
|
-
channelID,
|
|
490
|
-
portID,
|
|
491
|
-
rChannelID,
|
|
492
|
-
rPortID,
|
|
493
|
-
order,
|
|
494
|
-
);
|
|
495
|
-
const localAddr = await E(attemptP).getLocalAddress();
|
|
496
|
-
void E(attemptP).accept({
|
|
497
|
-
localAddress: `${localAddr}/ibc-channel/${channelID}`,
|
|
498
|
-
handler: rchandler,
|
|
499
|
-
});
|
|
500
|
-
break;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
case 'receivePacket': {
|
|
504
|
-
const { packet } = obj;
|
|
505
|
-
const {
|
|
506
|
-
data: data64,
|
|
507
|
-
destination_port: portID,
|
|
508
|
-
destination_channel: channelID,
|
|
509
|
-
} = packet;
|
|
510
|
-
const channelKey = `${channelID}:${portID}`;
|
|
511
|
-
const connP = channelKeyToConnP.get(channelKey);
|
|
512
|
-
const data = base64ToBytes(data64);
|
|
513
|
-
|
|
514
|
-
await E(connP)
|
|
515
|
-
.send(data)
|
|
516
|
-
.then(ack => {
|
|
517
|
-
const realAck = ack || DEFAULT_ACKNOWLEDGEMENT;
|
|
518
|
-
const ack64 = dataToBase64(realAck);
|
|
519
|
-
return callIBCDevice('receiveExecuted', { packet, ack: ack64 });
|
|
520
|
-
})
|
|
521
|
-
.catch(e => console.error(e));
|
|
522
|
-
break;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
case 'acknowledgementPacket': {
|
|
526
|
-
const { packet, acknowledgement } = obj;
|
|
527
|
-
const {
|
|
528
|
-
sequence,
|
|
529
|
-
source_channel: channelID,
|
|
530
|
-
source_port: portID,
|
|
531
|
-
} = packet;
|
|
532
|
-
const channelKey = `${channelID}:${portID}`;
|
|
533
|
-
const seqToAck = channelKeyToSeqAck.get(channelKey);
|
|
534
|
-
const ackDeferred = seqToAck.get(sequence);
|
|
535
|
-
ackDeferred.resolve(base64ToBytes(acknowledgement));
|
|
536
|
-
seqToAck.delete(sequence);
|
|
537
|
-
break;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
case 'timeoutPacket': {
|
|
541
|
-
const { packet } = obj;
|
|
542
|
-
const {
|
|
543
|
-
sequence,
|
|
544
|
-
source_channel: channelID,
|
|
545
|
-
source_port: portID,
|
|
546
|
-
} = packet;
|
|
547
|
-
const channelKey = `${channelID}:${portID}`;
|
|
548
|
-
const seqToAck = channelKeyToSeqAck.get(channelKey);
|
|
549
|
-
const ackDeferred = seqToAck.get(sequence);
|
|
550
|
-
ackDeferred.reject(Error(`Packet timed out`));
|
|
551
|
-
seqToAck.delete(sequence);
|
|
552
|
-
break;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
case 'channelCloseInit':
|
|
556
|
-
case 'channelCloseConfirm': {
|
|
557
|
-
const { portID, channelID } = obj;
|
|
558
|
-
const channelKey = `${channelID}:${portID}`;
|
|
559
|
-
if (channelKeyToConnP.has(channelKey)) {
|
|
560
|
-
const connP = channelKeyToConnP.get(channelKey);
|
|
561
|
-
channelKeyToConnP.delete(channelKey);
|
|
562
|
-
void E(connP).close();
|
|
563
|
-
}
|
|
564
|
-
break;
|
|
565
|
-
}
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
);
|
|
566
792
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
ibcSendPacket(packet, seqToAck, relativeTimeoutNs).then(
|
|
573
|
-
ack => console.info('Manual packet', packet, 'acked:', ack),
|
|
574
|
-
e => console.warn('Manual packet', packet, 'failed:', e),
|
|
575
|
-
);
|
|
576
|
-
break;
|
|
577
|
-
}
|
|
793
|
+
/** @param {IBCDevice} ibcdev */
|
|
794
|
+
const makeIBCProtocolHandlerKit = ibcdev => {
|
|
795
|
+
const { protocolHandler, bridgeHandler } = makeIBCProtocolKit(ibcdev);
|
|
796
|
+
return harden({ protocolHandler, bridgeHandler });
|
|
797
|
+
};
|
|
578
798
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
799
|
+
/** @param {IBCDevice} ibcdev */
|
|
800
|
+
const provideIBCProtocolHandlerKit = ibcdev => {
|
|
801
|
+
if (ibcdevToKit.has(ibcdev)) {
|
|
802
|
+
return ibcdevToKit.get(ibcdev);
|
|
803
|
+
}
|
|
804
|
+
const kit = makeIBCProtocolHandlerKit(ibcdev);
|
|
805
|
+
ibcdevToKit.init(ibcdev, kit);
|
|
806
|
+
return kit;
|
|
807
|
+
};
|
|
808
|
+
return provideIBCProtocolHandlerKit;
|
|
809
|
+
};
|
|
810
|
+
harden(prepareIBCProtocol);
|
|
811
|
+
|
|
812
|
+
/** @param {Zone} zone */
|
|
813
|
+
export const prepareCallbacks = zone => {
|
|
814
|
+
return zone.exoClass(
|
|
815
|
+
'callbacks',
|
|
816
|
+
undefined,
|
|
817
|
+
/** @param {ScopedBridgeManager<'dibc'>} dibcBridgeManager */
|
|
818
|
+
dibcBridgeManager => ({ dibcBridgeManager }),
|
|
819
|
+
{
|
|
820
|
+
/**
|
|
821
|
+
* @param {string} method
|
|
822
|
+
* @param {any} obj
|
|
823
|
+
*/
|
|
824
|
+
downcall(method, obj) {
|
|
825
|
+
const { dibcBridgeManager } = this.state;
|
|
826
|
+
return E(dibcBridgeManager).toBridge({
|
|
827
|
+
...obj,
|
|
828
|
+
type: 'IBC_METHOD',
|
|
829
|
+
method,
|
|
830
|
+
});
|
|
831
|
+
},
|
|
583
832
|
},
|
|
584
|
-
|
|
585
|
-
}
|
|
833
|
+
);
|
|
834
|
+
};
|