@calimero-network/mero-js 17.0.0 → 18.1.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/dist/index.cjs CHANGED
@@ -846,34 +846,15 @@ var AdminApiClient = class {
846
846
  return this.httpClient.get("/admin-api/is-authed");
847
847
  }
848
848
  // ---- Application Management ----
849
- async installApplication(request) {
850
- return unwrap(await this.httpClient.post("/admin-api/install-application", request));
851
- }
852
849
  /**
853
- * Resolve a `package@version` to its registry artifact URL and install it.
854
- * Node install is URL-based (no node-side package+version resolution), so this
855
- * fetches the bundle manifest from the registry, derives the `.mpk` artifact
856
- * URL, then calls {@link installApplication}. `registryUrl` is the registry
857
- * origin. This is the discrete "download" step an Updates flow pairs with a
858
- * subsequent `upgradeGroup`.
850
+ * Install a published application by its `package@version` coordinates. The
851
+ * node resolves and fetches them from its own configured `[registry]`, so no
852
+ * URL is passed and none is accepted. A 502 means the node's source has
853
+ * nothing published at those coordinates. This is the discrete "download"
854
+ * step an Updates flow pairs with a subsequent `upgradeGroup`.
859
855
  */
860
- async installFromRegistry(registryUrl, packageName, version) {
861
- const base = new URL(registryUrl).origin;
862
- const manifestUrl = new URL(
863
- `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,
864
- base
865
- ).toString();
866
- const resp = await fetchRegistry(manifestUrl, "manifest", `${packageName}@${version}`);
867
- const bundle = await resp.json();
868
- const pkg = encodeURIComponent(bundle.package);
869
- const ver = encodeURIComponent(bundle.appVersion);
870
- const artifactUrl = `${base}/artifacts/${pkg}/${ver}/${pkg}-${ver}.mpk`;
871
- return this.installApplication({
872
- url: artifactUrl,
873
- package: bundle.package,
874
- version: bundle.appVersion,
875
- metadata: []
876
- });
856
+ async installApplication(request) {
857
+ return unwrap(await this.httpClient.post("/admin-api/install-application", request));
877
858
  }
878
859
  /**
879
860
  * List a package's published versions from the registry, newest-first by
@@ -1285,6 +1266,128 @@ var AdminApiClient = class {
1285
1266
  async listNamespaceGroups(namespaceId) {
1286
1267
  return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}/groups`));
1287
1268
  }
1269
+ // ---- Account Devices & Pairing ----
1270
+ /**
1271
+ * Mint this node a device for an account that already lives somewhere else -
1272
+ * the first half of pairing, run on the joining node.
1273
+ *
1274
+ * Publishes nothing and needs no key: it produces the device id, the two
1275
+ * public keys and the signature that the account holder's
1276
+ * {@link completeAccountPairing} certifies, plus a code to read out to them
1277
+ * over a channel the payload does not travel on. Until that second half runs,
1278
+ * the device this mints is inert.
1279
+ *
1280
+ * Takes a set of namespaces rather than one, and takes it from the caller
1281
+ * because this node cannot discover it: a node that is a member of nothing can
1282
+ * neither read the account's namespace set off a DAG nor derive it. One device
1283
+ * covers however many are named - the certificate is over the account, not a
1284
+ * scope - so there is one id and one code to hand over regardless.
1285
+ */
1286
+ async initAccountPairing(request) {
1287
+ return unwrap(
1288
+ await this.httpClient.post("/admin-api/account/pair-init", request)
1289
+ );
1290
+ }
1291
+ /**
1292
+ * Certify a device another node minted, link it, and deliver its scope keys -
1293
+ * the second half of pairing, run on the node that holds the account root.
1294
+ *
1295
+ * Every field but `applications` is copied verbatim out of that node's
1296
+ * {@link initAccountPairing} answer. Only this side can complete it: the
1297
+ * certificate is signed by the account root, which never leaves the node that
1298
+ * holds it.
1299
+ *
1300
+ * The scope is named in applications, not namespaces, because that is the
1301
+ * question a person can answer - a namespace is an implementation unit they
1302
+ * never chose. Leave it out to grant every application.
1303
+ */
1304
+ async completeAccountPairing(request) {
1305
+ return unwrap(
1306
+ await this.httpClient.post("/admin-api/account/pair-complete", request)
1307
+ );
1308
+ }
1309
+ /**
1310
+ * Re-run the pairing fan-out for a device this account already certified,
1311
+ * against the namespaces this node takes part in now.
1312
+ *
1313
+ * Pairing is a snapshot, and this is how it is repeated. A namespace created
1314
+ * or joined afterwards holds no binding for a device paired before it, and the
1315
+ * symptom is silence - the device simply never sees that namespace. Nothing
1316
+ * but the id is needed to repair it: the certificate is already held here,
1317
+ * root-signed and naming no namespace, so a fresh endorsement and a key wrap
1318
+ * are all a later namespace is missing. The device does not have to be online.
1319
+ *
1320
+ * Passing `applications` widens the device's stored scope as well as
1321
+ * repairing. Passing none - or an empty list - repairs against the scope
1322
+ * already stored, which is deliberately NOT the "every application" that an
1323
+ * empty list means on {@link completeAccountPairing}: overloading it here
1324
+ * would make the accidental request the widest one.
1325
+ */
1326
+ async relinkAccountDevice(deviceId, request) {
1327
+ return unwrap(
1328
+ await this.httpClient.post(
1329
+ `/admin-api/account/devices/${deviceId}/relink`,
1330
+ request ?? {}
1331
+ )
1332
+ );
1333
+ }
1334
+ /**
1335
+ * Every device of this account, as this node sees them - its own included.
1336
+ *
1337
+ * Joined from the node-local certificate cache and the live bindings of every
1338
+ * namespace this node takes part in, so it is this node's view rather than a
1339
+ * global one: a device certified by another holder appears with an empty
1340
+ * `applications`, because the certificate that would name its scope is not
1341
+ * cached here.
1342
+ *
1343
+ * The wire wraps this in `devices` rather than the usual `data`; the array is
1344
+ * what a caller wants, so that wrapper is not passed on.
1345
+ */
1346
+ async listAccountDevices() {
1347
+ const response = await this.httpClient.get("/admin-api/account/devices");
1348
+ return response.devices;
1349
+ }
1350
+ /**
1351
+ * Every application this account speaks in, with the namespaces targeting each.
1352
+ *
1353
+ * What a device-scoping UI lists: {@link completeAccountPairing} and
1354
+ * {@link relinkAccountDevice} both take applications, and this is where the
1355
+ * ids they take come from. Derived from the namespaces this node takes part
1356
+ * in, so an application installed with no namespace yet is absent - it has
1357
+ * nothing to scope a device to until one exists.
1358
+ *
1359
+ * Wrapped in `applications` on the wire rather than `data`, unwrapped here for
1360
+ * the same reason {@link listAccountDevices} unwraps `devices`.
1361
+ */
1362
+ async listAccountApplications() {
1363
+ const response = await this.httpClient.get(
1364
+ "/admin-api/account/applications"
1365
+ );
1366
+ return response.applications;
1367
+ }
1368
+ /**
1369
+ * Withdraw a device from this account, terminally.
1370
+ *
1371
+ * Two authorities reach the same endpoint. An admin may revoke any device and
1372
+ * rotates the scope key as it goes. The account holder may revoke its own with
1373
+ * a root-signed `proof`, which does not rotate - so read
1374
+ * {@link RevokeAccountDeviceResponseData.revokedIn} rather than assuming the
1375
+ * device lost its access: a namespace reporting `keyRotated: false` has
1376
+ * stopped the device writing but leaves it able to read until an admin
1377
+ * rotates.
1378
+ *
1379
+ * `namespaceId` names where to publish from, not the extent of the revocation:
1380
+ * a device belongs to the account, so every namespace holding a binding for it
1381
+ * is withdrawn from and reported back.
1382
+ */
1383
+ async revokeAccountDevice(namespaceId, request) {
1384
+ return unwrap(
1385
+ await this.httpClient.post(
1386
+ `/admin-api/namespaces/${namespaceId}/account/revoke`,
1387
+ request
1388
+ )
1389
+ );
1390
+ }
1288
1391
  // ---- Group Management ----
1289
1392
  async getGroupInfo(groupId) {
1290
1393
  return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}`));