@agoric/network 0.1.1-dev-50c9518.0 → 0.1.1-dev-d15cb41.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 CHANGED
@@ -57,15 +57,12 @@ E(home.ibcport[0]).connect(remoteEndpoint, connectionHandler)
57
57
 
58
58
  The other side of `connect()` is a "listening port". These ports are waiting for inbound connections to be established.
59
59
 
60
- To get a listening port, you need a `NetworkInterface` object (such as the one on your `ag-solo` under `home.network`) and ask it to `bindPort()` to an endpoint. You can either provide a specific port name, or allow the API to allocate a random one for you. The endpoint specifies the type of connection that this port will be able to accept (IBC, TCP, etc), and some properties of that connection. `bindPort()` uses a "multiaddress" to encode this information.
60
+ To get a listening port, you need a `NetworkInterface` object (such as the one on your `ag-solo` under `home.network`) and ask it for a port, via the `PortAllocator`.
61
61
 
62
62
  ```js
63
63
  // ask for a random allocation - ends with a slash
64
- E(home.network).bindPort('/ibc-port/')
65
- .then(port => usePort(port));
66
-
67
- // or ask for a specific port name
68
- E(home.network).bindPort('/ibc-port/my-cool-port-name')
64
+ E(home.network).getPortAllocator()
65
+ .then(portAllocator => E(portAllocator).allocateCustomIBCPort())
69
66
  .then(port => usePort(port));
70
67
  ```
71
68
 
@@ -147,7 +144,7 @@ Note that if you want to listen on this port again, you can just call `port.addL
147
144
 
148
145
  ### Closing the Port Entirely
149
146
 
150
- Removing a listener doesn't release the port address to make it available for other `bindPort()` requests. You can call:
147
+ Removing a listener doesn't release the port address to make it available for other `PortAllocator` requests. You can call:
151
148
 
152
149
  ```js
153
150
  port.revoke();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/network",
3
- "version": "0.1.1-dev-50c9518.0+50c9518",
3
+ "version": "0.1.1-dev-d15cb41.0+d15cb41",
4
4
  "description": "Agoric's network protocol API",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -21,19 +21,19 @@
21
21
  "author": "Agoric",
22
22
  "license": "Apache-2.0",
23
23
  "dependencies": {
24
- "@agoric/assert": "0.6.1-dev-50c9518.0+50c9518",
25
- "@agoric/internal": "0.3.3-dev-50c9518.0+50c9518",
26
- "@agoric/store": "0.9.3-dev-50c9518.0+50c9518",
27
- "@agoric/vat-data": "0.5.3-dev-50c9518.0+50c9518",
24
+ "@agoric/assert": "0.6.1-dev-d15cb41.0+d15cb41",
25
+ "@agoric/internal": "0.3.3-dev-d15cb41.0+d15cb41",
26
+ "@agoric/store": "0.9.3-dev-d15cb41.0+d15cb41",
27
+ "@agoric/vat-data": "0.5.3-dev-d15cb41.0+d15cb41",
28
28
  "@endo/base64": "^1.0.4",
29
29
  "@endo/far": "^1.1.1",
30
30
  "@endo/patterns": "^1.3.1",
31
31
  "@endo/promise-kit": "^1.1.1"
32
32
  },
33
33
  "devDependencies": {
34
- "@agoric/swingset-liveslots": "0.10.3-dev-50c9518.0+50c9518",
35
- "@agoric/swingset-vat": "0.32.3-dev-50c9518.0+50c9518",
36
- "@agoric/zone": "0.2.3-dev-50c9518.0+50c9518",
34
+ "@agoric/swingset-liveslots": "0.10.3-dev-d15cb41.0+d15cb41",
35
+ "@agoric/swingset-vat": "0.32.3-dev-d15cb41.0+d15cb41",
36
+ "@agoric/zone": "0.2.3-dev-d15cb41.0+d15cb41",
37
37
  "@endo/bundle-source": "^3.2.2",
38
38
  "ava": "^5.3.0",
39
39
  "c8": "^9.1.0"
@@ -70,5 +70,5 @@
70
70
  "typeCoverage": {
71
71
  "atLeast": 89.73
72
72
  },
73
- "gitHead": "50c9518a689ad12d2ae331e158cf148b02bfdcb6"
73
+ "gitHead": "d15cb41b5dc7d3c47a1bc4c034ae74adfc7f838a"
74
74
  }
package/src/network.d.ts CHANGED
@@ -89,6 +89,19 @@ export function prepareEchoConnectionKit(zone: import("@agoric/base-zone").Zone)
89
89
  onListen(port: any, _listenHandler: any): Promise<void>;
90
90
  };
91
91
  }>;
92
+ export function preparePortAllocator(zone: import("@agoric/base-zone").Zone, { watch }: ReturnType<(zone: import("@agoric/base-zone").Zone, powers?: {
93
+ isRetryableReason?: ((reason: any) => boolean) | undefined;
94
+ watchPromise?: ((p: PromiseLike<any>, watcher: import("@agoric/vow/src/watch-promise.js").PromiseWatcher, ...args: unknown[]) => void) | undefined;
95
+ } | undefined) => {
96
+ when: <T, TResult1 = import("@agoric/vow").Unwrap<T>, TResult2 = never>(specimenP: T, onFulfilled?: ((value: import("@agoric/vow/src/types.js").Unwrap<T>) => TResult1 | PromiseLike<TResult1>) | undefined, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined) => Promise<TResult1 | TResult2>;
97
+ watch: <T_1 = unknown, TResult1_1 = T_1, TResult2_1 = T_1, C = unknown>(specimenP: import("@agoric/vow/src/types.js").ERef<T_1 | import("@agoric/vow/src/types.js").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>;
98
+ makeVowKit: <T_2>() => import("@agoric/vow").VowKit<T_2>;
99
+ allVows: (vows: any) => import("@agoric/vow").Vow<any>;
100
+ }>): (args_0?: any) => import("@endo/exo").Guarded<{
101
+ allocateCustomIBCPort(specifiedName?: string): import("@agoric/vow").Vow<any>;
102
+ allocateICAControllerPort(): import("@agoric/vow").Vow<any>;
103
+ allocateCustomLocalPort(specifiedName?: string): import("@agoric/vow").Vow<any>;
104
+ }>;
92
105
  export type ConnectionOpts = {
93
106
  addrs: Endpoint[];
94
107
  handlers: import("@agoric/vow").Remote<Required<ConnectionHandler>>[];
@@ -1 +1 @@
1
- {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["network.js"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,kCAFW,MAAM,YAahB;AAwsCD;;;;;GAKG;AACH,qDAHW,OAAO,mBAAmB,EAAE,IAAI,sBAChC,UAAU,QAlvCX,OAAO,mBACjB,EAAE,IAAI;;wBAIL,gBAED,WAAU,OAAQ,kCAAoB,EAGtC,cADc,WAAW,SACnB;;uFAHY,CAAC,yBAGnB,OAAO,0BAAY,EAAE,MAAM,CAAC,CAAC,CAAC;uFAkJc,OAAO,0BAAY,EAC9D,IAAI,CAAC,GAAC,GAAG,OAAO,0BAAY,EAAE,GAAG,CAAC,GAAC,CAAC,CAAC;;;EAqlCsB;;;;IAmCpD;;;;;OAKG;qCAHQ,QAAQ,cACR,QAAQ;;;IAgEnB;;;;;OAKG;kDAHQ,QAAQ;;GAiD1B;AAx4CD;;;GAGG;AACH,qCAAsC;AAG/B,0CADK,OAAO,aAWlB;AA2IM,0CARI,OAAO,cAAc,EAAE,IAAI,YAC3B,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SACzD,QAAQ,YACR,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SACzD,QAAQ,kBACR,CAAC,IAAI,EAAE,cAAc,KAAK,UAAU,yEAgD9C;AA66BM,6CAHI,OAAO,mBAAmB,EAAE,IAAI,UAChC,UAAU,oCAtnCnB,IAAI;;8FASN,cADc;;oJACO,MAAM;0HAmJ1B,IAAI,0CAA0B,GAAG;;;EA09B0B,iDAO7C,QAAQ,CA2BtB;AAOM,+CAFI,OAAO,mBAAmB,EAAE,IAAI;;QAsCnC;;;;WAIG;+BAHQ,UAAU,SACV,KAAK,sBACL,iBAAiB;QAU5B;;;;WAIG;6BAHQ,UAAU,YACV,WAAW;;;;YAftB;;;;eAIG;mCAHQ,UAAU,SACV,KAAK,sBACL,iBAAiB;YAU5B;;;;eAIG;iCAHQ,UAAU,YACV,WAAW;;;;GAyB7B;;WAlsCa,QAAQ,EAAE;cACV,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE;WAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;aAC5B,YAAY,CAAC,QAAQ,CAAC;OACtB,CAAC,GAAC,CAAC;OACH,CAAC,GAAC,CAAC"}
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["network.js"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,kCAFW,MAAM,YAahB;AAstCD;;;;;GAKG;AACH,qDAHW,OAAO,mBAAmB,EAAE,IAAI,sBAChC,UAAU,QAhwCX,OAAO,mBACjB,EAAE,IAAI;;wBAIL,gBAED,WAAU,OAAQ,kCAAoB,EAGtC,cADc,WAAW,SACnB;;uFAHY,CAAC,yBAGnB,OAAO,0BAAY,EAAE,MAAM,CAAC,CAAC,CAAC;uFA8IxB,OAAM,0BACJ,EAAE,IACT,CAAK,GAAH,GAAG,OAAO,0BAEZ,EAAK,GAAA,CAAC,GAAC,CACR,CAAC;;;EAmmC2D;;;;IAmCpD;;;;;OAKG;qCAHQ,QAAQ,cACR,QAAQ;;;IAgEnB;;;;;OAKG;kDAHQ,QAAQ;;GAiD1B;AAt5CD;;;GAGG;AACH,qCAAsC;AAG/B,0CADK,OAAO,aAWlB;AAyJM,0CARI,OAAO,cAAc,EAAE,IAAI,YAC3B,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SACzD,QAAQ,YACR,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SACzD,QAAQ,kBACR,CAAC,IAAI,EAAE,cAAc,KAAK,UAAU,yEAgD9C;AA66BM,6CAHI,OAAO,mBAAmB,EAAE,IAAI,UAChC,UAAU,oCApoCnB,IAAI;;8FASN,cADc;;oJACO,MAAM;0HA+IjB,IACT,0CAEK,GAAA;;;EAy+BsD,iDAO7C,QAAQ,CA2BtB;AAOM,+CAFI,OAAO,mBAAmB,EAAE,IAAI;;QAsCnC;;;;WAIG;+BAHQ,UAAU,SACV,KAAK,sBACL,iBAAiB;QAU5B;;;;WAIG;6BAHQ,UAAU,YACV,WAAW;;;;YAftB;;;;eAIG;mCAHQ,UAAU,SACV,KAAK,sBACL,iBAAiB;YAU5B;;;;eAIG;iCAHQ,UAAU,YACV,WAAW;;;;GAyB7B;AAsKM,2CAHI,OAAO,mBAAmB,EAAE,IAAI,aAChC,UAAU,oCA75CnB,IAAI;;8FASN,cADc;;oJACO,MAAM;0HA+IjB,IACT,0CAEK,GAAA;;;EAkwCsD;;;;GAqDzD;;WA35CW,QAAQ,EAAE;cACV,OAAO,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE;WAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;aAC5B,YAAY,CAAC,QAAQ,CAAC;OACtB,CAAC,GAAC,CAAC;OACH,CAAC,GAAC,CAAC"}
package/src/network.js CHANGED
@@ -46,6 +46,20 @@ export function getPrefixes(addr) {
46
46
  return ret;
47
47
  }
48
48
 
49
+ /**
50
+ * Validate IBC port name
51
+ * @param {string} specifiedName
52
+ */
53
+ function throwIfInvalidPortName(specifiedName) {
54
+ // Contains between 2 and 128 characters
55
+ // Can contain alphanumeric characters
56
+ // Valid symbols: ., ,, _, +, -, #, [, ], <, >
57
+ const portNameRegex = new RegExp('^[a-zA-Z0-9.,_+\\-#<>\\[\\]]{2,128}$');
58
+ if (!portNameRegex.test(specifiedName)) {
59
+ throw new Error(`Invalid IBC port name: ${specifiedName}`);
60
+ }
61
+ }
62
+
49
63
  /**
50
64
  * @typedef {object} ConnectionOpts
51
65
  * @property {Endpoint[]} addrs
@@ -1426,3 +1440,61 @@ export function prepareLoopbackProtocolHandler(zone, { watch, allVows }) {
1426
1440
 
1427
1441
  return makeLoopbackProtocolHandler;
1428
1442
  }
1443
+
1444
+ /**
1445
+ *
1446
+ * @param {import('@agoric/base-zone').Zone} zone
1447
+ * @param {ReturnType<import('@agoric/vow').prepareVowTools>} powers
1448
+ */
1449
+ export const preparePortAllocator = (zone, { watch }) =>
1450
+ zone.exoClass(
1451
+ 'PortAllocator',
1452
+ M.interface('PortAllocator', {
1453
+ allocateCustomIBCPort: M.callWhen()
1454
+ .optional(M.string())
1455
+ .returns(Shape.Vow$(Shape.Port)),
1456
+ allocateICAControllerPort: M.callWhen().returns(Shape.Vow$(Shape.Port)),
1457
+ allocateCustomLocalPort: M.callWhen()
1458
+ .optional(M.string())
1459
+ .returns(Shape.Vow$(Shape.Port)),
1460
+ }),
1461
+ ({ protocol }) => ({ protocol, lastICAPortNum: 0n }),
1462
+ {
1463
+ allocateCustomIBCPort(specifiedName = '') {
1464
+ const { state } = this;
1465
+ let localAddr = `/ibc-port/`;
1466
+
1467
+ if (specifiedName) {
1468
+ throwIfInvalidPortName(specifiedName);
1469
+
1470
+ localAddr = `/ibc-port/custom-${specifiedName}`;
1471
+ }
1472
+
1473
+ // Allocate an IBC port with a unique generated name.
1474
+ return watch(E(state.protocol).bindPort(localAddr));
1475
+ },
1476
+ allocateICAControllerPort() {
1477
+ const { state } = this;
1478
+ state.lastICAPortNum += 1n;
1479
+ return watch(
1480
+ E(state.protocol).bindPort(
1481
+ `/ibc-port/icacontroller-${state.lastICAPortNum}`,
1482
+ ),
1483
+ );
1484
+ },
1485
+ allocateCustomLocalPort(specifiedName = '') {
1486
+ const { state } = this;
1487
+
1488
+ let localAddr = `/local/`;
1489
+
1490
+ if (specifiedName) {
1491
+ throwIfInvalidPortName(specifiedName);
1492
+
1493
+ localAddr = `/local/custom-${specifiedName}`;
1494
+ }
1495
+
1496
+ // Allocate a local port with a unique generated name.
1497
+ return watch(E(state.protocol).bindPort(localAddr));
1498
+ },
1499
+ },
1500
+ );
package/src/types.d.ts CHANGED
@@ -210,6 +210,7 @@ type ProtocolImpl = {
210
210
  */
211
211
  outbound: (port: Remote<Port>, remoteAddr: Endpoint, connectionHandler: Remote<ConnectionHandler>) => PromiseVow<Connection>;
212
212
  };
213
+ type PortAllocator = ReturnType<ReturnType<typeof import("@agoric/network").preparePortAllocator>>;
213
214
  import type { PromiseVow } from '@agoric/vow';
214
215
  import type { Remote } from '@agoric/vow';
215
216
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":";;;qBAO8D,CAAC,sCAAqB,CAAC,mBAD7D,GAAG,EAAE,KAAK,GAAG,IACyB,CAAC,AAAjD,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,OAAO,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;;;;aAK5E,MAAM;;;;;gBAIN,MAAM;;;;;;;;;;;;;;;;;;uBAWI,QAAQ;;;;;;;;;;qBAMjB,MAAM,QAAQ;;;;;;;;sBAKf,QAAQ;;;;;;;;;;;;;;;;;;;;;;8CAeL,QAAQ,cACP,QAAQ;;;;gDAMT,QAAQ,cACP,QAAQ;;;;yCAIe,GAAG;;;;;;;;;;;wBASzB,KAAK,SACX,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;;;;;;qBAIjB,MAAM,QAAQ;;;;sBAEd,MAAM,QAAQ;;;;;;;;;0DAOZ,QAAQ,cACP,QAAQ;;;;uDAMf,KAAK,uCAEH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;yDAKjB,WAAW;;;;;mBAKZ,GAAG,GAAG,IAAI;;;;;;;;;;;;;;;;;;gCAeG,QAAQ;;;;4CAIlB,QAAQ;;;;8CAMR,QAAQ;;;;oDAOR,QAAQ;;;;qDAOR,QAAQ,UACX,QAAQ;;;;+CAML,QAAQ,UACX,QAAQ;;;;8CAOL,QAAQ;;;;;;;;;mBAMH,kBAAkB;;;;;qBAEzB,MAAM,QAAQ;;;;;sBAEd,MAAM,QAAQ;;;;;;;;;;;;;;uBAKL,QAAQ;;;;0BAGd,QAAQ,cACR,QAAQ;;;;+CAKR,QAAQ;;gCAvLa,aAAa;4BAAb,aAAa"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":";;;qBAO8D,CAAC,sCAAqB,CAAC,mBAD7D,GAAG,EAAE,KAAK,GAAG,IACyB,CAAC,AAAjD,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,OAAO,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;;;;aAK5E,MAAM;;;;;gBAIN,MAAM;;;;;;;;;;;;;;;;;;uBAWI,QAAQ;;;;;;;;;;qBAMjB,MAAM,QAAQ;;;;;;;;sBAKf,QAAQ;;;;;;;;;;;;;;;;;;;;;;8CAeL,QAAQ,cACP,QAAQ;;;;gDAMT,QAAQ,cACP,QAAQ;;;;yCAIe,GAAG;;;;;;;;;;;wBASzB,KAAK,SACX,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;;;;;;qBAIjB,MAAM,QAAQ;;;;sBAEd,MAAM,QAAQ;;;;;;;;;0DAOZ,QAAQ,cACP,QAAQ;;;;uDAMf,KAAK,uCAEH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;yDAKjB,WAAW;;;;;mBAKZ,GAAG,GAAG,IAAI;;;;;;;;;;;;;;;;;;gCAeG,QAAQ;;;;4CAIlB,QAAQ;;;;8CAMR,QAAQ;;;;oDAOR,QAAQ;;;;qDAOR,QAAQ,UACX,QAAQ;;;;+CAML,QAAQ,UACX,QAAQ;;;;8CAOL,QAAQ;;;;;;;;;mBAMH,kBAAkB;;;;;qBAEzB,MAAM,QAAQ;;;;;sBAEd,MAAM,QAAQ;;;;;;;;;;;;;;uBAKL,QAAQ;;;;0BAGd,QAAQ,cACR,QAAQ;;;;+CAKR,QAAQ;;qBAMX,UAAU,CAAC,UAAU,CAAC,cAAc,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;gCA7LrD,aAAa;4BAAb,aAAa"}
package/src/types.js CHANGED
@@ -188,3 +188,5 @@
188
188
  * ) => PromiseVow<Connection>} outbound
189
189
  * Create an outbound connection
190
190
  */
191
+
192
+ /** @typedef {ReturnType<ReturnType<typeof import('@agoric/network').preparePortAllocator>>} PortAllocator */