@agoric/vats 0.15.2-dev-00cccfc.0 → 0.15.2-dev-e2e36cc.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 +17 -17
- package/src/ibc.d.ts +46 -26
- package/src/ibc.d.ts.map +1 -1
- package/src/ibc.js +130 -95
- package/src/types.d.ts +2 -2
- package/src/vat-ibc.d.ts +20 -20
- package/tools/ibc-utils.d.ts +15 -0
- package/tools/ibc-utils.d.ts.map +1 -0
- package/tools/ibc-utils.js +89 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/vats",
|
|
3
|
-
"version": "0.15.2-dev-
|
|
3
|
+
"version": "0.15.2-dev-e2e36cc.0+e2e36cc",
|
|
4
4
|
"description": "Agoric's Vat library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"author": "Agoric",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agoric/assert": "0.6.1-dev-
|
|
26
|
-
"@agoric/cosmic-proto": "0.4.1-dev-
|
|
27
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
28
|
-
"@agoric/governance": "0.10.4-dev-
|
|
29
|
-
"@agoric/internal": "0.3.3-dev-
|
|
30
|
-
"@agoric/network": "0.1.1-dev-
|
|
31
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
32
|
-
"@agoric/store": "0.9.3-dev-
|
|
33
|
-
"@agoric/swingset-vat": "0.32.3-dev-
|
|
34
|
-
"@agoric/time": "0.3.3-dev-
|
|
35
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
36
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
37
|
-
"@agoric/zone": "0.2.3-dev-
|
|
25
|
+
"@agoric/assert": "0.6.1-dev-e2e36cc.0+e2e36cc",
|
|
26
|
+
"@agoric/cosmic-proto": "0.4.1-dev-e2e36cc.0+e2e36cc",
|
|
27
|
+
"@agoric/ertp": "0.16.3-dev-e2e36cc.0+e2e36cc",
|
|
28
|
+
"@agoric/governance": "0.10.4-dev-e2e36cc.0+e2e36cc",
|
|
29
|
+
"@agoric/internal": "0.3.3-dev-e2e36cc.0+e2e36cc",
|
|
30
|
+
"@agoric/network": "0.1.1-dev-e2e36cc.0+e2e36cc",
|
|
31
|
+
"@agoric/notifier": "0.6.3-dev-e2e36cc.0+e2e36cc",
|
|
32
|
+
"@agoric/store": "0.9.3-dev-e2e36cc.0+e2e36cc",
|
|
33
|
+
"@agoric/swingset-vat": "0.32.3-dev-e2e36cc.0+e2e36cc",
|
|
34
|
+
"@agoric/time": "0.3.3-dev-e2e36cc.0+e2e36cc",
|
|
35
|
+
"@agoric/vat-data": "0.5.3-dev-e2e36cc.0+e2e36cc",
|
|
36
|
+
"@agoric/zoe": "0.26.3-dev-e2e36cc.0+e2e36cc",
|
|
37
|
+
"@agoric/zone": "0.2.3-dev-e2e36cc.0+e2e36cc",
|
|
38
38
|
"@endo/far": "^1.1.1",
|
|
39
39
|
"@endo/import-bundle": "^1.1.1",
|
|
40
40
|
"@endo/marshal": "^1.4.1",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"jessie.js": "^0.3.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
48
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-e2e36cc.0+e2e36cc",
|
|
49
49
|
"@endo/bundle-source": "^3.2.2",
|
|
50
50
|
"@endo/init": "^1.1.1",
|
|
51
51
|
"ava": "^5.3.0",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"workerThreads": false
|
|
77
77
|
},
|
|
78
78
|
"typeCoverage": {
|
|
79
|
-
"atLeast":
|
|
79
|
+
"atLeast": 91.5
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "e2e36cc1e1c015fc517a179019184fdc81f3e809"
|
|
82
82
|
}
|
package/src/ibc.d.ts
CHANGED
|
@@ -1,43 +1,61 @@
|
|
|
1
|
-
export function prepareIBCConnectionHandler(zone: Zone): (args_0
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
export function prepareIBCConnectionHandler(zone: Zone): (args_0: {
|
|
2
|
+
protocolUtils: any;
|
|
3
|
+
channelKeyToConnP: MapStore<string, import('@agoric/vow').Remote<Connection>>;
|
|
4
|
+
channelKeyToSeqAck: MapStore<string, MapStore<number, import('@agoric/vow').VowKit<Bytes>>>;
|
|
5
|
+
}, args_1: {
|
|
6
|
+
channelID: `channel-${number}`;
|
|
7
|
+
portID: string;
|
|
8
|
+
rChannelID: `channel-${number}`;
|
|
9
|
+
rPortID: string;
|
|
10
|
+
order: 'ORDERED' | 'UNORDERED';
|
|
11
|
+
}) => import("@endo/exo").Guarded<{
|
|
12
|
+
/** @type {Required<ConnectionHandler>['onOpen']} */
|
|
13
|
+
onOpen(connection: globalThis.Remote<Connection>, localAddr: string, remoteAddr: string, c: globalThis.Remote<ConnectionHandler>): PromiseVow<void>;
|
|
14
|
+
/** @type {Required<ConnectionHandler>['onReceive']} */
|
|
15
|
+
onReceive(connection: globalThis.Remote<Connection>, ack: string, c: globalThis.Remote<ConnectionHandler>, opts?: Record<string, any> | undefined): PromiseVow<string>;
|
|
16
|
+
/** @type {Required<ConnectionHandler>['onClose']} */
|
|
17
|
+
onClose(connection: globalThis.Remote<Connection>, reason?: any, c?: globalThis.Remote<ConnectionHandler> | undefined): PromiseVow<void>;
|
|
15
18
|
}>;
|
|
16
19
|
export function prepareIBCProtocol(zone: Zone, powers: {
|
|
17
20
|
when: <T, TResult1 = import("@agoric/vow").Unwrap<T>, TResult2 = never>(specimenP: T, onFulfilled?: ((value: import("@agoric/vow").Unwrap<T>) => TResult1 | PromiseLike<TResult1>) | undefined, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined) => Promise<TResult1 | TResult2>;
|
|
18
|
-
watch: <T_1 =
|
|
21
|
+
watch: <T_1 = unknown, TResult1_1 = T_1, TResult2_1 = T_1, C = unknown>(specimenP: import("@agoric/vow").ERef<T_1 | import("@agoric/vow").Vow<T_1>>, watcher?: import("@agoric/vow").Watcher<T_1, TResult1_1, TResult2_1, any> | undefined, watcherContext?: C | undefined) => import("@agoric/vow").Vow<TResult1_1 | TResult2_1>;
|
|
19
22
|
makeVowKit: <T_2>() => VowKit<T_2>;
|
|
20
23
|
allVows: (vows: any) => import("@agoric/vow").Vow<any>;
|
|
21
|
-
}): (ibcdev:
|
|
24
|
+
}): (ibcdev: {
|
|
25
|
+
downcall: (method: string, args: object) => Promise<any>;
|
|
26
|
+
}) => {
|
|
22
27
|
protocolHandler: ProtocolHandler;
|
|
23
28
|
bridgeHandler: BridgeHandler;
|
|
24
29
|
} | {
|
|
25
30
|
protocolHandler: import("@endo/exo").Guarded<{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
/** @type {Required<ProtocolHandler>['onCreate']} */
|
|
32
|
+
onCreate(protocol: globalThis.Remote<ProtocolImpl>, p: globalThis.Remote<ProtocolHandler>): PromiseVow<void>;
|
|
33
|
+
/** @type {Required<ProtocolHandler>['onInstantiate']} */
|
|
34
|
+
onInstantiate(port: globalThis.Remote<Port>, localAddr: string, remote: string, p: globalThis.Remote<ProtocolHandler>): PromiseVow<string>;
|
|
35
|
+
/** @type {Required<ProtocolHandler>['generatePortID']} */
|
|
36
|
+
generatePortID(localAddr: string, p: globalThis.Remote<ProtocolHandler>): PromiseVow<string>;
|
|
37
|
+
/** @type {Required<ProtocolHandler>['onBind']} */
|
|
38
|
+
onBind(port: globalThis.Remote<Port>, localAddr: string, p: globalThis.Remote<ProtocolHandler>): PromiseVow<void>;
|
|
39
|
+
/** @type {Required<ProtocolHandler>['onConnect']} */
|
|
40
|
+
onConnect(port: globalThis.Remote<Port>, localAddr: string, remote: string, c: globalThis.Remote<ConnectionHandler>, p: globalThis.Remote<ProtocolHandler>): PromiseVow<AttemptDescription>;
|
|
41
|
+
/** @type {Required<ProtocolHandler>['onListen']} */
|
|
42
|
+
onListen(port: globalThis.Remote<Port>, localAddr: string, listenHandler: globalThis.Remote<ListenHandler>, p: globalThis.Remote<ProtocolHandler>): PromiseVow<void>;
|
|
43
|
+
/** @type {Required<ProtocolHandler>['onListenRemove']} */
|
|
44
|
+
onListenRemove(port: globalThis.Remote<Port>, localAddr: string, listenHandler: globalThis.Remote<ListenHandler>, p: globalThis.Remote<ProtocolHandler>): PromiseVow<void>;
|
|
45
|
+
/** @type {Required<ProtocolHandler>['onRevoke']} */
|
|
46
|
+
onRevoke(port: globalThis.Remote<Port>, localAddr: string, p: globalThis.Remote<ProtocolHandler>): PromiseVow<void>;
|
|
34
47
|
}>;
|
|
35
48
|
bridgeHandler: import("@endo/exo").Guarded<{
|
|
36
|
-
|
|
49
|
+
/** @param {IBCEvent<IBCBridgeEvent>} obj */
|
|
50
|
+
fromBridge(obj: IBCEvent<IBCBridgeEvent>): Promise<import("@agoric/vow").Vow<any> | undefined>;
|
|
37
51
|
}>;
|
|
38
52
|
};
|
|
39
53
|
export function prepareCallbacks(zone: Zone): (dibcBridgeManager: ScopedBridgeManager) => import("@endo/exo").Guarded<{
|
|
40
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @param {string} method
|
|
56
|
+
* @param {any} obj
|
|
57
|
+
*/
|
|
58
|
+
downcall(method: string, obj: any): Promise<any>;
|
|
41
59
|
}>;
|
|
42
60
|
export type OnConnectP = {
|
|
43
61
|
vow: import("@agoric/vow").Vow<AttemptDescription>;
|
|
@@ -53,6 +71,8 @@ export type Outbound = Omit<ConnectingInfo, "counterparty" | "channelID" | "coun
|
|
|
53
71
|
import type { Zone } from '@agoric/base-zone';
|
|
54
72
|
import type { VowKit } from '@agoric/vow';
|
|
55
73
|
import type { BridgeHandler } from './types.js';
|
|
74
|
+
import type { IBCBridgeEvent } from './types.js';
|
|
75
|
+
import type { IBCEvent } from './types.js';
|
|
56
76
|
import type { ScopedBridgeManager } from './types.js';
|
|
57
77
|
import type { VowResolver } from '@agoric/vow';
|
|
58
78
|
import type { ConnectingInfo } from './types.js';
|
package/src/ibc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ibc.d.ts","sourceRoot":"","sources":["ibc.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ibc.d.ts","sourceRoot":"","sources":["ibc.js"],"names":[],"mappings":"AA6CO;mBAciB,GAAG;uBACC,SACvB,MAAY,EACZ,OAAa,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CACzC;wBACmB,SACxB,MAAY,EACZ,SAAe,MAAM,EAAE,OAAO,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CACtD;;;YAIO,MAAM;;aAEL,MAAM;WACR,SAAS,GAAG,WAAW;;IAuBjC,oDAAoD;;IAepD,uDAAuD;;IAoBvD,qDAAqD;;GA0B1D;AAMM;;;;;;cAOS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,CAAC;;qBAOpC,eAAe;;;;QAoDjC,oDAAoD;;QAKpD,yDAAyD;;QAKzD,0DAA0D;;QAK1D,kDAAkD;;QAalD,qDAAqD;;QAiDrD,oDAAoD;;QAIpD,0DAA0D;;QAI1D,oDAAoD;;;;QAgBpD,4CAA4C;;;EAudnD;AAIM;IAOD;;;OAGG;qBAFQ,MAAM,OACN,GAAG;GAYnB;;;;;;eArxBe,QAAQ;gBACP,UAAU;kBACR;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;;0BAbf,mBAAmB;4BACc,aAAa;mCAFqI,YAAY;oCAAZ,YAAY;8BAAZ,YAAY;yCAAZ,YAAY;iCAE9J,aAAa;oCAFqI,YAAY"}
|
package/src/ibc.js
CHANGED
|
@@ -7,6 +7,14 @@ import { dataToBase64, base64ToBytes } from '@agoric/network';
|
|
|
7
7
|
|
|
8
8
|
import '@agoric/store/exported.js';
|
|
9
9
|
import '@agoric/network/exported.js';
|
|
10
|
+
import {
|
|
11
|
+
localAddrToPortID,
|
|
12
|
+
decodeRemoteIbcAddress,
|
|
13
|
+
encodeLocalIbcAddress,
|
|
14
|
+
encodeRemoteIbcAddress,
|
|
15
|
+
} from '../tools/ibc-utils.js';
|
|
16
|
+
|
|
17
|
+
/** @import {LocalIbcAddress, RemoteIbcAddress} from '../tools/ibc-utils.js' */
|
|
10
18
|
|
|
11
19
|
// CAVEAT: IBC acks cannot be empty, as the Cosmos IAVL tree cannot represent
|
|
12
20
|
// empty acknowledgements as distinct from unacknowledged packets.
|
|
@@ -16,14 +24,14 @@ const DEFAULT_ACKNOWLEDGEMENT = '\x00';
|
|
|
16
24
|
const DEFAULT_PACKET_TIMEOUT_NS = 60n * 60n * 1_000_000_000n;
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
|
-
* @import {BridgeHandler, ScopedBridgeManager, ConnectingInfo, IBCChannelID, IBCChannelOrdering, IBCEvent, IBCPacket, IBCPortID,
|
|
27
|
+
* @import {BridgeHandler, ScopedBridgeManager, ConnectingInfo, IBCChannelID, IBCChannelOrdering, IBCEvent, IBCPacket, IBCPortID, IBCDowncallPacket, IBCDowncallMethod, IBCDowncall, IBCBridgeEvent} from './types.js';
|
|
20
28
|
* @import {Zone} from '@agoric/base-zone';
|
|
21
29
|
* @import {Remote, VowKit, VowResolver, VowTools} from '@agoric/vow';
|
|
22
30
|
*/
|
|
23
31
|
|
|
32
|
+
/** @typedef {VowKit<AttemptDescription>} OnConnectP */
|
|
33
|
+
|
|
24
34
|
/**
|
|
25
|
-
* @typedef {VowKit<AttemptDescription>} OnConnectP
|
|
26
|
-
*
|
|
27
35
|
* @typedef {Omit<
|
|
28
36
|
* ConnectingInfo,
|
|
29
37
|
* 'counterparty' | 'channelID' | 'counterpartyVersion'
|
|
@@ -47,6 +55,26 @@ export const prepareIBCConnectionHandler = zone => {
|
|
|
47
55
|
const makeIBCConnectionHandler = zone.exoClass(
|
|
48
56
|
'IBCConnectionHandler',
|
|
49
57
|
undefined,
|
|
58
|
+
/**
|
|
59
|
+
* @param {{
|
|
60
|
+
* protocolUtils: any;
|
|
61
|
+
* channelKeyToConnP: MapStore<
|
|
62
|
+
* string,
|
|
63
|
+
* import('@agoric/vow').Remote<Connection>
|
|
64
|
+
* >;
|
|
65
|
+
* channelKeyToSeqAck: MapStore<
|
|
66
|
+
* string,
|
|
67
|
+
* MapStore<number, import('@agoric/vow').VowKit<Bytes>>
|
|
68
|
+
* >;
|
|
69
|
+
* }} param0
|
|
70
|
+
* @param {{
|
|
71
|
+
* channelID: IBCChannelID;
|
|
72
|
+
* portID: string;
|
|
73
|
+
* rChannelID: IBCChannelID;
|
|
74
|
+
* rPortID: string;
|
|
75
|
+
* order: 'ORDERED' | 'UNORDERED';
|
|
76
|
+
* }} param1
|
|
77
|
+
*/
|
|
50
78
|
(
|
|
51
79
|
{ protocolUtils, channelKeyToConnP, channelKeyToSeqAck },
|
|
52
80
|
{ channelID, portID, rChannelID, rPortID, order },
|
|
@@ -67,6 +95,7 @@ export const prepareIBCConnectionHandler = zone => {
|
|
|
67
95
|
};
|
|
68
96
|
},
|
|
69
97
|
{
|
|
98
|
+
/** @type {Required<ConnectionHandler>['onOpen']} */
|
|
70
99
|
async onOpen(conn, localAddr, remoteAddr, _handler) {
|
|
71
100
|
const { channelID, portID, channelKeyToConnP } = this.state;
|
|
72
101
|
|
|
@@ -81,14 +110,7 @@ export const prepareIBCConnectionHandler = zone => {
|
|
|
81
110
|
|
|
82
111
|
channelKeyToConnP.init(channelKey, conn);
|
|
83
112
|
},
|
|
84
|
-
/**
|
|
85
|
-
* @param {Connection} _conn
|
|
86
|
-
* @param {Bytes} packetBytes
|
|
87
|
-
* @param {ConnectionHandler} _handler
|
|
88
|
-
* @param {object} root0
|
|
89
|
-
* @param {bigint} [root0.relativeTimeoutNs]
|
|
90
|
-
* @returns {PromiseVow<Bytes>} Acknowledgement data
|
|
91
|
-
*/
|
|
113
|
+
/** @type {Required<ConnectionHandler>['onReceive']} */
|
|
92
114
|
async onReceive(
|
|
93
115
|
_conn,
|
|
94
116
|
packetBytes,
|
|
@@ -108,7 +130,8 @@ export const prepareIBCConnectionHandler = zone => {
|
|
|
108
130
|
};
|
|
109
131
|
return protocolUtils.ibcSendPacket(packet, relativeTimeoutNs);
|
|
110
132
|
},
|
|
111
|
-
|
|
133
|
+
/** @type {Required<ConnectionHandler>['onClose']} */
|
|
134
|
+
async onClose() {
|
|
112
135
|
const { portID, channelID } = this.state;
|
|
113
136
|
const { protocolUtils, channelKeyToSeqAck } = this.state;
|
|
114
137
|
|
|
@@ -166,12 +189,11 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
166
189
|
/**
|
|
167
190
|
* Create a handler for the IBC protocol, both from the network and from the
|
|
168
191
|
* bridge.
|
|
169
|
-
*
|
|
170
|
-
* @param {IBCDevice} ibcdev
|
|
171
192
|
*/
|
|
172
193
|
const makeIBCProtocolKit = zone.exoClassKit(
|
|
173
194
|
'IBCProtocolHandler',
|
|
174
195
|
undefined,
|
|
196
|
+
/** @param {IBCDevice} ibcdev */
|
|
175
197
|
ibcdev => {
|
|
176
198
|
/** @type {MapStore<string, Remote<Connection>>} */
|
|
177
199
|
const channelKeyToConnP = detached.mapStore('channelKeyToConnP');
|
|
@@ -206,73 +228,46 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
206
228
|
},
|
|
207
229
|
{
|
|
208
230
|
protocolHandler: {
|
|
209
|
-
|
|
231
|
+
/** @type {Required<ProtocolHandler>['onCreate']} */
|
|
232
|
+
async onCreate(impl) {
|
|
210
233
|
console.debug('IBC onCreate');
|
|
211
234
|
this.state.protocolImpl = impl;
|
|
212
235
|
},
|
|
236
|
+
/** @type {Required<ProtocolHandler>['onInstantiate']} */
|
|
213
237
|
async onInstantiate() {
|
|
214
238
|
// The IBC channel is not known until after handshake.
|
|
215
239
|
return '';
|
|
216
240
|
},
|
|
217
|
-
|
|
241
|
+
/** @type {Required<ProtocolHandler>['generatePortID']} */
|
|
242
|
+
async generatePortID() {
|
|
218
243
|
this.state.lastPortID += 1n;
|
|
219
244
|
return `port-${this.state.lastPortID}`;
|
|
220
245
|
},
|
|
221
|
-
|
|
246
|
+
/** @type {Required<ProtocolHandler>['onBind']} */
|
|
247
|
+
async onBind(_port, localAddr) {
|
|
222
248
|
const { util } = this.facets;
|
|
223
249
|
const { portToPendingConns } = this.state;
|
|
224
250
|
|
|
225
|
-
|
|
251
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
252
|
+
const portID = localAddrToPortID(localAddr);
|
|
226
253
|
portToPendingConns.init(portID, detached.setStore('pendingConns'));
|
|
227
254
|
const packet = {
|
|
228
255
|
source_port: portID,
|
|
229
256
|
};
|
|
230
257
|
return util.downcall('bindPort', { packet });
|
|
231
258
|
},
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
localAddr,
|
|
235
|
-
remoteAddr,
|
|
236
|
-
_chandler,
|
|
237
|
-
_protocolHandler,
|
|
238
|
-
) {
|
|
259
|
+
/** @type {Required<ProtocolHandler>['onConnect']} */
|
|
260
|
+
async onConnect(_port, localAddr, remoteAddr) {
|
|
239
261
|
const { util } = this.facets;
|
|
240
262
|
const { portToPendingConns, srcPortToOutbounds } = this.state;
|
|
241
263
|
|
|
242
264
|
console.debug('IBC onConnect', localAddr, remoteAddr);
|
|
243
|
-
|
|
265
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
266
|
+
const portID = localAddrToPortID(localAddr);
|
|
244
267
|
const pendingConns = portToPendingConns.get(portID);
|
|
245
268
|
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
);
|
|
249
|
-
if (!match) {
|
|
250
|
-
throw TypeError(
|
|
251
|
-
`Remote address ${remoteAddr} must be '(/ibc-hop/CONNECTION)*/ibc-port/PORT/(ordered|unordered)/VERSION'`,
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const hops = [];
|
|
256
|
-
let h = match[1];
|
|
257
|
-
while (h) {
|
|
258
|
-
const m = h.match(/^\/ibc-hop\/([^/]+)/);
|
|
259
|
-
if (!m) {
|
|
260
|
-
throw Error(
|
|
261
|
-
`internal: ${JSON.stringify(
|
|
262
|
-
h,
|
|
263
|
-
)} did not begin with "/ibc-hop/XXX"`,
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
h = h.substr(m[0].length);
|
|
267
|
-
hops.push(m[1]);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Generate a circuit.
|
|
271
|
-
/** @type {IBCPortID} */
|
|
272
|
-
const rPortID = match[2];
|
|
273
|
-
/** @type {IBCChannelOrdering} */
|
|
274
|
-
const order = match[3] === 'ordered' ? 'ORDERED' : 'UNORDERED';
|
|
275
|
-
const version = match[4];
|
|
269
|
+
const { rPortID, hops, order, version } =
|
|
270
|
+
decodeRemoteIbcAddress(remoteAddr);
|
|
276
271
|
|
|
277
272
|
const kit = makeVowKit();
|
|
278
273
|
|
|
@@ -310,18 +305,20 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
310
305
|
|
|
311
306
|
return kit.vow;
|
|
312
307
|
},
|
|
313
|
-
|
|
308
|
+
/** @type {Required<ProtocolHandler>['onListen']} */
|
|
309
|
+
async onListen(_port, localAddr) {
|
|
314
310
|
console.debug('IBC onListen', localAddr);
|
|
315
311
|
},
|
|
316
|
-
|
|
312
|
+
/** @type {Required<ProtocolHandler>['onListenRemove']} */
|
|
313
|
+
async onListenRemove(_port, localAddr) {
|
|
317
314
|
console.debug('IBC onListenRemove', localAddr);
|
|
318
315
|
},
|
|
319
|
-
|
|
320
|
-
|
|
316
|
+
/** @type {Required<ProtocolHandler>['onRevoke']} */
|
|
317
|
+
async onRevoke(_port, localAddr) {
|
|
321
318
|
const { portToPendingConns } = this.state;
|
|
322
|
-
|
|
323
319
|
console.debug('IBC onRevoke', localAddr);
|
|
324
|
-
|
|
320
|
+
// @ts-expect-error may not be LocalIbcAddress
|
|
321
|
+
const portID = localAddrToPortID(localAddr);
|
|
325
322
|
|
|
326
323
|
const pendingConns = portToPendingConns.get(portID);
|
|
327
324
|
portToPendingConns.delete(portID);
|
|
@@ -332,6 +329,7 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
332
329
|
},
|
|
333
330
|
},
|
|
334
331
|
bridgeHandler: {
|
|
332
|
+
/** @param {IBCEvent<IBCBridgeEvent>} obj */
|
|
335
333
|
async fromBridge(obj) {
|
|
336
334
|
const {
|
|
337
335
|
protocolImpl,
|
|
@@ -348,7 +346,6 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
348
346
|
await null;
|
|
349
347
|
switch (obj.event) {
|
|
350
348
|
case 'channelOpenInit': {
|
|
351
|
-
/** @type {IBCEvent<'channelOpenInit'>} */
|
|
352
349
|
const {
|
|
353
350
|
channelID,
|
|
354
351
|
portID,
|
|
@@ -357,7 +354,7 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
357
354
|
order,
|
|
358
355
|
version,
|
|
359
356
|
asyncVersions,
|
|
360
|
-
} = obj;
|
|
357
|
+
} = /** @type {IBCEvent<'channelOpenInit'>} */ (obj);
|
|
361
358
|
if (!asyncVersions) {
|
|
362
359
|
// Synchronous versions have already been negotiated.
|
|
363
360
|
break;
|
|
@@ -381,7 +378,6 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
381
378
|
}
|
|
382
379
|
case 'channelOpenTry': {
|
|
383
380
|
// They're (more or less politely) asking if we are listening, so make an attempt.
|
|
384
|
-
/** @type {IBCEvent<'channelOpenTry'>} */
|
|
385
381
|
const {
|
|
386
382
|
portID,
|
|
387
383
|
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
@@ -389,11 +385,16 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
389
385
|
order,
|
|
390
386
|
version,
|
|
391
387
|
counterpartyVersion: rVersion,
|
|
392
|
-
} = obj;
|
|
388
|
+
} = /** @type {IBCEvent<'channelOpenTry'>} */ (obj);
|
|
393
389
|
|
|
394
|
-
const localAddr =
|
|
395
|
-
const
|
|
396
|
-
|
|
390
|
+
const localAddr = encodeLocalIbcAddress(portID, order, version);
|
|
391
|
+
const remoteAddr = encodeRemoteIbcAddress(
|
|
392
|
+
hops,
|
|
393
|
+
rPortID,
|
|
394
|
+
order,
|
|
395
|
+
rVersion,
|
|
396
|
+
rChannelID,
|
|
397
|
+
);
|
|
397
398
|
|
|
398
399
|
// See if we allow an inbound attempt for this address pair (without
|
|
399
400
|
// rejecting).
|
|
@@ -420,14 +421,14 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
420
421
|
|
|
421
422
|
case 'channelOpenAck': {
|
|
422
423
|
// Complete the pending outbound connection.
|
|
423
|
-
/** @type {IBCEvent<'channelOpenAck'>} */
|
|
424
424
|
const {
|
|
425
425
|
portID,
|
|
426
426
|
channelID,
|
|
427
427
|
counterparty: { port_id: rPortID, channel_id: rChannelID },
|
|
428
428
|
counterpartyVersion: rVersion,
|
|
429
429
|
connectionHops: rHops,
|
|
430
|
-
} = obj;
|
|
430
|
+
} = /** @type {IBCEvent<'channelOpenAck'>} */ (obj);
|
|
431
|
+
|
|
431
432
|
const outbounds = this.state.srcPortToOutbounds.has(portID)
|
|
432
433
|
? [...this.state.srcPortToOutbounds.get(portID)]
|
|
433
434
|
: [];
|
|
@@ -460,8 +461,13 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
460
461
|
}
|
|
461
462
|
|
|
462
463
|
// Finish the outbound connection.
|
|
463
|
-
const
|
|
464
|
-
|
|
464
|
+
const remoteAddress = encodeRemoteIbcAddress(
|
|
465
|
+
rHops,
|
|
466
|
+
rPortID,
|
|
467
|
+
chanInfo.order,
|
|
468
|
+
rVersion,
|
|
469
|
+
rChannelID,
|
|
470
|
+
);
|
|
465
471
|
const localAddress = `${localAddr}/${chanInfo.order.toLowerCase()}/${rVersion}/ibc-channel/${channelID}`;
|
|
466
472
|
const rchandler = makeIBCConnectionHandler(
|
|
467
473
|
{
|
|
@@ -486,8 +492,9 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
486
492
|
}
|
|
487
493
|
|
|
488
494
|
case 'channelOpenConfirm': {
|
|
489
|
-
|
|
490
|
-
|
|
495
|
+
const { portID, channelID } =
|
|
496
|
+
/** @type {IBCEvent<'channelOpenConfirm'>} */ (obj);
|
|
497
|
+
|
|
491
498
|
const channelKey = `${channelID}:${portID}`;
|
|
492
499
|
channelKeyToAttempt.has(channelKey) ||
|
|
493
500
|
Fail`${channelKey}: did not expect channelOpenConfirm`;
|
|
@@ -525,8 +532,7 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
525
532
|
}
|
|
526
533
|
|
|
527
534
|
case 'receivePacket': {
|
|
528
|
-
/** @type {IBCEvent<'receivePacket'>} */
|
|
529
|
-
const { packet } = obj;
|
|
535
|
+
const { packet } = /** @type {IBCEvent<'receivePacket'>} */ (obj);
|
|
530
536
|
const {
|
|
531
537
|
data: data64,
|
|
532
538
|
destination_port: portID,
|
|
@@ -542,26 +548,30 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
542
548
|
}
|
|
543
549
|
|
|
544
550
|
case 'acknowledgementPacket': {
|
|
545
|
-
|
|
546
|
-
|
|
551
|
+
const { packet, acknowledgement } =
|
|
552
|
+
/** @type {IBCEvent<'acknowledgementPacket'>} */ (obj);
|
|
547
553
|
const {
|
|
548
554
|
sequence,
|
|
549
555
|
source_channel: channelID,
|
|
550
556
|
source_port: portID,
|
|
551
557
|
} = packet;
|
|
558
|
+
if (sequence === undefined)
|
|
559
|
+
throw TypeError('acknowledgementPacket without sequence');
|
|
552
560
|
const ackKit = util.findAckKit(channelID, portID, sequence);
|
|
553
561
|
ackKit.resolver.resolve(base64ToBytes(acknowledgement));
|
|
554
562
|
break;
|
|
555
563
|
}
|
|
556
564
|
|
|
557
565
|
case 'timeoutPacket': {
|
|
558
|
-
/** @type {IBCEvent<'timeoutPacket'>} */
|
|
559
|
-
const { packet } = obj;
|
|
566
|
+
const { packet } = /** @type {IBCEvent<'timeoutPacket'>} */ (obj);
|
|
560
567
|
const {
|
|
561
568
|
sequence,
|
|
562
569
|
source_channel: channelID,
|
|
563
570
|
source_port: portID,
|
|
564
571
|
} = packet;
|
|
572
|
+
if (sequence === undefined)
|
|
573
|
+
throw TypeError('timeoutPacket without sequence');
|
|
574
|
+
|
|
565
575
|
const ackKit = util.findAckKit(channelID, portID, sequence);
|
|
566
576
|
ackKit.resolver.reject(Error(`Packet timed out`));
|
|
567
577
|
break;
|
|
@@ -569,7 +579,9 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
569
579
|
|
|
570
580
|
case 'channelCloseInit':
|
|
571
581
|
case 'channelCloseConfirm': {
|
|
572
|
-
const { portID, channelID } =
|
|
582
|
+
const { portID, channelID } =
|
|
583
|
+
// could be either but that complicates line wrapping
|
|
584
|
+
/** @type {IBCEvent<'channelCloseInit'>} */ (obj);
|
|
573
585
|
const channelKey = `${channelID}:${portID}`;
|
|
574
586
|
if (channelKeyToConnP.has(channelKey)) {
|
|
575
587
|
const conn = channelKeyToConnP.get(channelKey);
|
|
@@ -580,8 +592,8 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
580
592
|
}
|
|
581
593
|
|
|
582
594
|
case 'sendPacket': {
|
|
583
|
-
|
|
584
|
-
|
|
595
|
+
const { packet, relativeTimeoutNs } =
|
|
596
|
+
/** @type {IBCEvent<'sendPacket'>} */ (obj);
|
|
585
597
|
util.ibcSendPacket(packet, relativeTimeoutNs).then(
|
|
586
598
|
ack => console.info('Manual packet', packet, 'acked:', ack),
|
|
587
599
|
e => console.warn('Manual packet', packet, 'failed:', e),
|
|
@@ -633,17 +645,12 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
633
645
|
const { vow } = util.findAckKit(channelID, portID, sequence);
|
|
634
646
|
return vow;
|
|
635
647
|
},
|
|
636
|
-
/** @param {string} localAddr */
|
|
637
|
-
localAddrToPortID(localAddr) {
|
|
638
|
-
const m = localAddr.match(/^\/ibc-port\/([-a-zA-Z0-9._+#[\]<>]+)$/);
|
|
639
|
-
if (!m) {
|
|
640
|
-
throw TypeError(
|
|
641
|
-
`Invalid port specification ${localAddr}; expected "/ibc-port/PORT"`,
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
return m[1];
|
|
645
|
-
},
|
|
646
648
|
|
|
649
|
+
/**
|
|
650
|
+
* @param {IBCChannelID} channelID
|
|
651
|
+
* @param {IBCPortID} portID
|
|
652
|
+
* @param {number} sequence
|
|
653
|
+
*/
|
|
647
654
|
findAckKit(channelID, portID, sequence) {
|
|
648
655
|
const { channelKeyToSeqAck } = this.state;
|
|
649
656
|
const channelKey = `${channelID}:${portID}`;
|
|
@@ -657,6 +664,10 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
657
664
|
},
|
|
658
665
|
},
|
|
659
666
|
ackWatcher: {
|
|
667
|
+
/**
|
|
668
|
+
* @param {string} ack
|
|
669
|
+
* @param {{ packet: any }} watcherContext
|
|
670
|
+
*/
|
|
660
671
|
onFulfilled(ack, watcherContext) {
|
|
661
672
|
const { packet } = watcherContext;
|
|
662
673
|
|
|
@@ -674,6 +685,21 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
674
685
|
},
|
|
675
686
|
},
|
|
676
687
|
protocolImplAttemptWatcher: {
|
|
688
|
+
/**
|
|
689
|
+
* @param {string} attemptedLocal
|
|
690
|
+
* @param {{
|
|
691
|
+
* channelID: IBCChannelID;
|
|
692
|
+
* portID: string;
|
|
693
|
+
* attempt: any;
|
|
694
|
+
* obj: any;
|
|
695
|
+
* asyncVersions: any;
|
|
696
|
+
* rPortID: string;
|
|
697
|
+
* rChannelID: IBCChannelID;
|
|
698
|
+
* order: IBCChannelOrdering;
|
|
699
|
+
* hops: any;
|
|
700
|
+
* version: string;
|
|
701
|
+
* }} watcherContext
|
|
702
|
+
*/
|
|
677
703
|
onFulfilled(attemptedLocal, watcherContext) {
|
|
678
704
|
const {
|
|
679
705
|
channelID,
|
|
@@ -736,6 +762,10 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
736
762
|
},
|
|
737
763
|
},
|
|
738
764
|
protocolImplInboundWatcher: {
|
|
765
|
+
/**
|
|
766
|
+
* @param {any} attempt
|
|
767
|
+
* @param {Record<string, any>} watchContext
|
|
768
|
+
*/
|
|
739
769
|
onFulfilled(attempt, watchContext) {
|
|
740
770
|
const { obj } = watchContext;
|
|
741
771
|
|
|
@@ -754,11 +784,13 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
754
784
|
},
|
|
755
785
|
);
|
|
756
786
|
|
|
787
|
+
/** @param {IBCDevice} ibcdev */
|
|
757
788
|
const makeIBCProtocolHandlerKit = ibcdev => {
|
|
758
789
|
const { protocolHandler, bridgeHandler } = makeIBCProtocolKit(ibcdev);
|
|
759
790
|
return harden({ protocolHandler, bridgeHandler });
|
|
760
791
|
};
|
|
761
792
|
|
|
793
|
+
/** @param {IBCDevice} ibcdev */
|
|
762
794
|
const provideIBCProtocolHandlerKit = ibcdev => {
|
|
763
795
|
if (ibcdevToKit.has(ibcdev)) {
|
|
764
796
|
return ibcdevToKit.get(ibcdev);
|
|
@@ -769,7 +801,6 @@ export const prepareIBCProtocol = (zone, powers) => {
|
|
|
769
801
|
};
|
|
770
802
|
return provideIBCProtocolHandlerKit;
|
|
771
803
|
};
|
|
772
|
-
|
|
773
804
|
harden(prepareIBCProtocol);
|
|
774
805
|
|
|
775
806
|
/** @param {Zone} zone */
|
|
@@ -780,6 +811,10 @@ export const prepareCallbacks = zone => {
|
|
|
780
811
|
/** @param {ScopedBridgeManager} dibcBridgeManager */
|
|
781
812
|
dibcBridgeManager => ({ dibcBridgeManager }),
|
|
782
813
|
{
|
|
814
|
+
/**
|
|
815
|
+
* @param {string} method
|
|
816
|
+
* @param {any} obj
|
|
817
|
+
*/
|
|
783
818
|
downcall(method, obj) {
|
|
784
819
|
const { dibcBridgeManager } = this.state;
|
|
785
820
|
return E(dibcBridgeManager).toBridge({
|
package/src/types.d.ts
CHANGED
|
@@ -167,8 +167,8 @@ type IBCPacketEvents = {
|
|
|
167
167
|
timeoutPacket: {
|
|
168
168
|
packet: IBCPacket;
|
|
169
169
|
};
|
|
170
|
-
channelCloseInit:
|
|
171
|
-
channelCloseConfirm:
|
|
170
|
+
channelCloseInit: ConnectingInfo; // TODO update
|
|
171
|
+
channelCloseConfirm: ConnectingInfo; // TODO update
|
|
172
172
|
sendPacket: { relativeTimeoutNs: bigint; packet: IBCPacket };
|
|
173
173
|
};
|
|
174
174
|
|
package/src/vat-ibc.d.ts
CHANGED
|
@@ -4,21 +4,21 @@ export function buildRootObject(_vatPowers: any, _args: any, baggage: any): {
|
|
|
4
4
|
bridgeHandler: import("./types.js").BridgeHandler;
|
|
5
5
|
} | {
|
|
6
6
|
protocolHandler: import("@endo/exo").Guarded<{
|
|
7
|
-
onCreate(
|
|
8
|
-
onInstantiate():
|
|
9
|
-
generatePortID(
|
|
10
|
-
onBind(port:
|
|
11
|
-
onConnect(port:
|
|
12
|
-
onListen(
|
|
13
|
-
onListenRemove(
|
|
14
|
-
onRevoke(
|
|
7
|
+
onCreate(protocol: Remote<ProtocolImpl>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
8
|
+
onInstantiate(port: Remote<Port>, localAddr: string, remote: string, p: Remote<ProtocolHandler>): PromiseVow<string>;
|
|
9
|
+
generatePortID(localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<string>;
|
|
10
|
+
onBind(port: Remote<Port>, localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
11
|
+
onConnect(port: Remote<Port>, localAddr: string, remote: string, c: Remote<ConnectionHandler>, p: Remote<ProtocolHandler>): PromiseVow<AttemptDescription>;
|
|
12
|
+
onListen(port: Remote<Port>, localAddr: string, listenHandler: Remote<ListenHandler>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
13
|
+
onListenRemove(port: Remote<Port>, localAddr: string, listenHandler: Remote<ListenHandler>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
14
|
+
onRevoke(port: Remote<Port>, localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
15
15
|
}>;
|
|
16
16
|
bridgeHandler: import("@endo/exo").Guarded<{
|
|
17
|
-
fromBridge(obj:
|
|
17
|
+
fromBridge(obj: import("./types.js").IBCEvent<import("./types.js").IBCBridgeEvent>): Promise<import("@agoric/vow").Vow<any> | undefined>;
|
|
18
18
|
}>;
|
|
19
19
|
};
|
|
20
20
|
makeCallbacks: (dibcBridgeManager: import("./types.js").ScopedBridgeManager) => import("@endo/exo").Guarded<{
|
|
21
|
-
downcall(method:
|
|
21
|
+
downcall(method: string, obj: any): Promise<any>;
|
|
22
22
|
}>;
|
|
23
23
|
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
24
24
|
createHandlers: (callbacks: any) => {
|
|
@@ -26,21 +26,21 @@ export function buildRootObject(_vatPowers: any, _args: any, baggage: any): {
|
|
|
26
26
|
bridgeHandler: import("./types.js").BridgeHandler;
|
|
27
27
|
} | {
|
|
28
28
|
protocolHandler: import("@endo/exo").Guarded<{
|
|
29
|
-
onCreate(
|
|
30
|
-
onInstantiate():
|
|
31
|
-
generatePortID(
|
|
32
|
-
onBind(port:
|
|
33
|
-
onConnect(port:
|
|
34
|
-
onListen(
|
|
35
|
-
onListenRemove(
|
|
36
|
-
onRevoke(
|
|
29
|
+
onCreate(protocol: Remote<ProtocolImpl>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
30
|
+
onInstantiate(port: Remote<Port>, localAddr: string, remote: string, p: Remote<ProtocolHandler>): PromiseVow<string>;
|
|
31
|
+
generatePortID(localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<string>;
|
|
32
|
+
onBind(port: Remote<Port>, localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
33
|
+
onConnect(port: Remote<Port>, localAddr: string, remote: string, c: Remote<ConnectionHandler>, p: Remote<ProtocolHandler>): PromiseVow<AttemptDescription>;
|
|
34
|
+
onListen(port: Remote<Port>, localAddr: string, listenHandler: Remote<ListenHandler>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
35
|
+
onListenRemove(port: Remote<Port>, localAddr: string, listenHandler: Remote<ListenHandler>, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
36
|
+
onRevoke(port: Remote<Port>, localAddr: string, p: Remote<ProtocolHandler>): PromiseVow<void>;
|
|
37
37
|
}>;
|
|
38
38
|
bridgeHandler: import("@endo/exo").Guarded<{
|
|
39
|
-
fromBridge(obj:
|
|
39
|
+
fromBridge(obj: import("./types.js").IBCEvent<import("./types.js").IBCBridgeEvent>): Promise<import("@agoric/vow").Vow<any> | undefined>;
|
|
40
40
|
}>;
|
|
41
41
|
};
|
|
42
42
|
makeCallbacks: (dibcBridgeManager: import("./types.js").ScopedBridgeManager) => import("@endo/exo").Guarded<{
|
|
43
|
-
downcall(method:
|
|
43
|
+
downcall(method: string, obj: any): Promise<any>;
|
|
44
44
|
}>;
|
|
45
45
|
}>;
|
|
46
46
|
//# sourceMappingURL=vat-ibc.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const REMOTE_ADDR_RE: RegExp;
|
|
2
|
+
/** @typedef {`/${string}ibc-port/${string}/${'ordered' | 'unordered'}/${string}`} RemoteIbcAddress */
|
|
3
|
+
export const LOCAL_ADDR_RE: RegExp;
|
|
4
|
+
export function decodeRemoteIbcAddress(remoteAddr: string): {
|
|
5
|
+
rPortID: string;
|
|
6
|
+
hops: `connection-${number}`[];
|
|
7
|
+
order: import("../src/types.js").IBCChannelOrdering;
|
|
8
|
+
version: string;
|
|
9
|
+
};
|
|
10
|
+
export function localAddrToPortID(localAddr: LocalIbcAddress): string;
|
|
11
|
+
export function encodeRemoteIbcAddress(hops: string[], rPortID: string, order: 'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED', rVersion: string, rChannelID: string): RemoteIbcAddress;
|
|
12
|
+
export function encodeLocalIbcAddress(portID: string, order: 'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED', version: string): string;
|
|
13
|
+
export type RemoteIbcAddress = `/${string}ibc-port/${string}/${'ordered' | 'unordered'}/${string}`;
|
|
14
|
+
export type LocalIbcAddress = `/ibc-port/${string}`;
|
|
15
|
+
//# sourceMappingURL=ibc-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ibc-utils.d.ts","sourceRoot":"","sources":["ibc-utils.js"],"names":[],"mappings":"AAAA,oCAC8G;AAE9G,sGAAsG;AAEtG,mCAA+E;AAIxE,mDADK,MAAM;;;;;EA8BjB;AAOM,6CAHI,eAAe,GACb,MAAM,CAWlB;AAWM,6CAPI,MAAM,EAAE,WACR,MAAM,SACN,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,YACjD,MAAM,cACN,MAAM,GACJ,gBAAgB,CAa5B;AAQM,8CAJI,MAAM,SACN,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,WACjD,MAAM,UAIhB;+BAnFa,IAAI,MAAM,YAAY,MAAM,IAAI,SAAS,GAAG,WAAW,IAAI,MAAM,EAAE;8BAGnE,aAAa,MAAM,EAAE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export const REMOTE_ADDR_RE =
|
|
2
|
+
/^(?<hops>\/ibc-hop\/[^/]+)*\/ibc-port\/(?<portID>[^/]+)\/(?<order>ordered|unordered)\/(?<version>[^/]+)$/s;
|
|
3
|
+
harden(REMOTE_ADDR_RE);
|
|
4
|
+
/** @typedef {`/${string}ibc-port/${string}/${'ordered' | 'unordered'}/${string}`} RemoteIbcAddress */
|
|
5
|
+
|
|
6
|
+
export const LOCAL_ADDR_RE = /^\/ibc-port\/(?<portID>[-a-zA-Z0-9._+#[\]<>]+)$/;
|
|
7
|
+
/** @typedef {`/ibc-port/${string}`} LocalIbcAddress */
|
|
8
|
+
|
|
9
|
+
/** @param {string} remoteAddr */
|
|
10
|
+
export const decodeRemoteIbcAddress = remoteAddr => {
|
|
11
|
+
const match = remoteAddr.match(REMOTE_ADDR_RE);
|
|
12
|
+
// .groups is to inform TS https://github.com/microsoft/TypeScript/issues/32098
|
|
13
|
+
if (!(match && match.groups)) {
|
|
14
|
+
throw TypeError(
|
|
15
|
+
`Remote address ${remoteAddr} must be '(/ibc-hop/CONNECTION)*/ibc-port/PORT/(ordered|unordered)/VERSION'`,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @type {import('../src/types.js').IBCConnectionID[]} */
|
|
20
|
+
const hops = [];
|
|
21
|
+
|
|
22
|
+
let h = match.groups.hops;
|
|
23
|
+
while (h) {
|
|
24
|
+
const m = h.match(/^\/ibc-hop\/(?<hop>[^/]+)/);
|
|
25
|
+
if (!m) {
|
|
26
|
+
throw Error(
|
|
27
|
+
`internal: ${JSON.stringify(h)} did not begin with "/ibc-hop/XXX"`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
h = h.substr(m[0].length);
|
|
31
|
+
// @ts-expect-error unchecked cast
|
|
32
|
+
hops.push(m.groups.hop);
|
|
33
|
+
}
|
|
34
|
+
// Generate a circuit.
|
|
35
|
+
const { portID: rPortID, version } = match.groups;
|
|
36
|
+
/** @type {import('../src/types.js').IBCChannelOrdering} */
|
|
37
|
+
const order = match.groups.order === 'ordered' ? 'ORDERED' : 'UNORDERED';
|
|
38
|
+
return { rPortID, hops, order, version };
|
|
39
|
+
};
|
|
40
|
+
harden(decodeRemoteIbcAddress);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {LocalIbcAddress} localAddr
|
|
44
|
+
* @returns {string}
|
|
45
|
+
*/
|
|
46
|
+
export const localAddrToPortID = localAddr => {
|
|
47
|
+
const m = localAddr.match(LOCAL_ADDR_RE);
|
|
48
|
+
// .groups is to inform TS https://github.com/microsoft/TypeScript/issues/32098
|
|
49
|
+
if (!(m && m.groups)) {
|
|
50
|
+
throw TypeError(
|
|
51
|
+
`Invalid port specification ${localAddr}; expected "/ibc-port/PORT"`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return m.groups.portID;
|
|
55
|
+
};
|
|
56
|
+
harden(localAddrToPortID);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {string[]} hops
|
|
60
|
+
* @param {string} rPortID
|
|
61
|
+
* @param {'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED'} order
|
|
62
|
+
* @param {string} rVersion
|
|
63
|
+
* @param {string} rChannelID
|
|
64
|
+
* @returns {RemoteIbcAddress}
|
|
65
|
+
*/
|
|
66
|
+
export const encodeRemoteIbcAddress = (
|
|
67
|
+
hops,
|
|
68
|
+
rPortID,
|
|
69
|
+
order,
|
|
70
|
+
rVersion,
|
|
71
|
+
rChannelID,
|
|
72
|
+
) => {
|
|
73
|
+
const ibcHops = hops.map(hop => `/ibc-hop/${hop}`).join('/');
|
|
74
|
+
return /** @type {RemoteIbcAddress} */ (
|
|
75
|
+
`${ibcHops}/ibc-port/${rPortID}/${order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
harden(encodeRemoteIbcAddress);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {string} portID
|
|
82
|
+
* @param {'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED'} order
|
|
83
|
+
* @param {string} version
|
|
84
|
+
*/
|
|
85
|
+
export const encodeLocalIbcAddress = (portID, order, version) => {
|
|
86
|
+
return `/ibc-port/${portID}/${order.toLowerCase()}/${version}`;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
harden(encodeLocalIbcAddress);
|