From 90891afbc465a1994f944ea7cc39107bfee81f96 Mon Sep 17 00:00:00 2001 From: Moe Jangda Date: Tue, 16 May 2023 04:59:37 -0500 Subject: [PATCH] implemented `protocol.send` and `record.send` Co-Authored-By: Frank Hinek --- package-lock.json | 908 +++++++++--------- packages/dids/package.json | 2 +- packages/web5-agent/package.json | 4 +- packages/web5-agent/src/web5-agent.ts | 32 +- .../web5-proxy-agent/src/web5-proxy-agent.ts | 6 +- packages/web5-user-agent/.mocharc.json | 3 + packages/web5-user-agent/karma.conf.cjs | 4 +- packages/web5-user-agent/package.json | 2 +- .../web5-user-agent/src/dwn-rpc-client.ts | 48 +- packages/web5-user-agent/src/utils.ts | 6 +- .../web5-user-agent/src/web5-user-agent.ts | 261 +++-- .../tests/common/web5-user-agent.spec.ts | 74 +- packages/web5/package.json | 2 +- packages/web5/src/dwn-api.ts | 46 +- packages/web5/src/protocol.ts | 36 + packages/web5/src/record.ts | 52 +- packages/web5/src/utils.ts | 28 +- .../fixtures/protocol-definitions/email.json | 49 + packages/web5/tests/fixtures/test-profiles.ts | 6 +- packages/web5/tests/record.spec.ts | 77 +- packages/web5/tests/web5-dwn.spec.ts | 51 +- 21 files changed, 929 insertions(+), 768 deletions(-) create mode 100644 packages/web5-user-agent/.mocharc.json create mode 100644 packages/web5/src/protocol.ts create mode 100644 packages/web5/tests/fixtures/protocol-definitions/email.json diff --git a/package-lock.json b/package-lock.json index a45cfda6d..329fe9a80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -597,18 +597,17 @@ } }, "node_modules/@ipld/dag-pb": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-2.1.18.tgz", - "integrity": "sha512-ZBnf2fuX9y3KccADURG5vb9FaOeMjFkCrNysB0PtftME/4iCTjxfaLoNq/IAh5fTqUOMXvryN6Jyka4ZGuMLIg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.3.tgz", + "integrity": "sha512-bOe+Z2ZJs9pmP/aIUBYMTdXq0i5z1x71qXeOIIhZvnKFLuzTIbbW0u5b7OfTGzUEbSv1dkUZBIXa7G/+OA8dnA==", "dependencies": { - "multiformats": "^9.5.4" + "multiformats": "^11.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" } }, - "node_modules/@ipld/dag-pb/node_modules/multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -691,19 +690,18 @@ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, "node_modules/@multiformats/murmur3": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-1.1.3.tgz", - "integrity": "sha512-wAPLUErGR8g6Lt+bAZn6218k9YQPym+sjszsXL6o4zfxbA22P+gxWZuuD9wDbwL55xrKO5idpcuQUX7/E3oHcw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.3.tgz", + "integrity": "sha512-YvLK1IrLnRckPsvXhOkZjaIGNonsEdD1dL3NPSaLilV/WjVYeBgnNZXTUsaPzFXGrIFM7motx+yCmmqzXO6gtQ==", "dependencies": { - "multiformats": "^9.5.4", + "multiformats": "^11.0.0", "murmurhash3js-revisited": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" } }, - "node_modules/@multiformats/murmur3/node_modules/multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - }, "node_modules/@noble/ed25519": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.0.tgz", @@ -930,9 +928,9 @@ "link": true }, "node_modules/@tbd54566975/dwn-sdk-js": { - "version": "0.0.31-unstable-2023-05-11-32b5f91", - "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.0.31-unstable-2023-05-11-32b5f91.tgz", - "integrity": "sha512-MV3AFCy0kCAd1phAzyr1RvaGB74i9V5jFusVQ8YJGJ+unuQW/AYc33ZTAoBdhsxon3TuXeWpiAFS0OWSwCjEQw==", + "version": "0.0.32-unstable-2023-05-15-1350300", + "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.0.32-unstable-2023-05-15-1350300.tgz", + "integrity": "sha512-ymPmSwfiXv+4G2nGet87RjBA1Xun7V7jIo6YZnNPIFqw+vbn9sMj1ikuydRrlvW1cE2eCznuE8fTzEoe4trcLQ==", "dependencies": { "@ipld/dag-cbor": "9.0.0", "@js-temporal/polyfill": "0.4.3", @@ -947,15 +945,15 @@ "@types/secp256k1": "4.0.3", "abstract-level": "1.0.3", "ajv": "8.12.0", - "blockstore-core": "3.0.0", + "blockstore-core": "4.1.0", "cross-fetch": "3.1.5", "date-fns": "2.28.0", "eccrypto": "1.1.6", "flat": "^5.0.2", - "interface-blockstore": "4.0.1", - "ipfs-unixfs": "6.0.9", - "ipfs-unixfs-exporter": "7.0.11", - "ipfs-unixfs-importer": "14.0.1", + "interface-blockstore": "5.2.0", + "interface-store": "^5.1.0", + "ipfs-unixfs-exporter": "13.1.4", + "ipfs-unixfs-importer": "15.1.4", "level": "8.0.0", "lodash": "4.17.21", "lru-cache": "7.12.0", @@ -1110,11 +1108,6 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, "node_modules/@types/mocha": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", @@ -1790,18 +1783,14 @@ } }, "node_modules/blockstore-core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-3.0.0.tgz", - "integrity": "sha512-5ZZB5nh6kErcjZ/CTK6lCwTIGlPdkTXbD8+2xLC4Fm0WGh7g2e2lW2bfURw7mvnPtSX1xV+sN4V2ndowSgIiHQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-4.1.0.tgz", + "integrity": "sha512-CxlavQ6Yri8Se/l7F6ug8AK9StcJK42UdnJQua3XlwoQUVGSuIRnY+q2wqFzuCAuv4m4a5pp/JH29GliV4EEgQ==", "dependencies": { "err-code": "^3.0.1", - "interface-blockstore": "^4.0.0", - "interface-store": "^3.0.0", - "it-all": "^2.0.0", - "it-drain": "^2.0.0", - "it-filter": "^2.0.0", - "it-take": "^2.0.0", - "multiformats": "^11.0.0" + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" }, "engines": { "node": ">=16.0.0", @@ -3208,8 +3197,7 @@ "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "node_modules/events": { "version": "3.3.0", @@ -3622,16 +3610,28 @@ "dev": true }, "node_modules/hamt-sharding": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-2.0.1.tgz", - "integrity": "sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", + "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", "dependencies": { "sparse-array": "^1.3.1", - "uint8arrays": "^3.0.0" + "uint8arrays": "^4.0.2" }, "engines": { - "node": ">=10.0.0", - "npm": ">=6.0.0" + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/hamt-sharding/node_modules/uint8arrays": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", + "integrity": "sha512-b+aKlI2oTnxnfeSQWV1sMacqSNxqhtXySaH6bflvONGxF8V/fT3ZlYH7z2qgGfydsvpVo4JUgM/Ylyfl2YouCg==", + "dependencies": { + "multiformats": "^11.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" } }, "node_modules/has": { @@ -3901,12 +3901,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/interface-blockstore": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-4.0.1.tgz", - "integrity": "sha512-ROWKGJls7vLeFaQtI3hZVCJOkUoZ05xAi2t2qysM4d7dwVKrfm5jUOqWh8JgLL7Iup3XqJ0mKXXZuwJ3s03RSw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.2.0.tgz", + "integrity": "sha512-lLW6fNP3PkBKghK9BsLuV8VMquL/o2lInomrTUizY/p4n7vxzVn3YT7qGTHywZzCcMIBeGMneDApGe21TNkg+g==", "dependencies": { - "interface-store": "^3.0.0", - "multiformats": "^11.0.0" + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" }, "engines": { "node": ">=16.0.0", @@ -3914,21 +3914,22 @@ } }, "node_modules/interface-store": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-3.0.4.tgz", - "integrity": "sha512-OjHUuGXbH4eXSBx1TF1tTySvjLldPLzRSYYXJwrEQI+XfH5JWYZofr0gVMV4F8XTwC+4V7jomDYkvGRmDSRKqQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-5.1.0.tgz", + "integrity": "sha512-mjUwX3XSoreoxCS3sXS3pSRsGnUjl9T06KBqt/T7AgE9Sgp4diH64ZyURJKnj2T5WmCvTbC0Dm+mwQV5hfLSBQ==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, "node_modules/ipfs-unixfs": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-6.0.9.tgz", - "integrity": "sha512-0DQ7p0/9dRB6XCb0mVCTli33GzIzSVx5udpJuVM47tGcD+W+Bl4LsnoLswd3ggNnNEakMv1FdoFITiEnchXDqQ==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.0.1.tgz", + "integrity": "sha512-SD9dqn14bfgMfkPstsR/2Av3zCzYMj2ntQJab4HZucgX4nNV6K7guZh4Hf3kiL8ONff1Ogft1ekFU083DIKEdQ==", "dependencies": { "err-code": "^3.0.1", - "protobufjs": "^6.10.2" + "protons-runtime": "^5.0.0", + "uint8arraylist": "^2.4.3" }, "engines": { "node": ">=16.0.0", @@ -3936,72 +3937,26 @@ } }, "node_modules/ipfs-unixfs-exporter": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-7.0.11.tgz", - "integrity": "sha512-qTYa69J7HbI2EIYNUddKPg9Y3rHkYZV0bNdmzZKA5+ZbwRVoUEuBW/cguEqTp22zHygh3sMnzYZFm0naVIdMgQ==", - "dependencies": { - "@ipld/dag-cbor": "^7.0.2", - "@ipld/dag-pb": "^2.0.2", - "@multiformats/murmur3": "^1.0.3", - "err-code": "^3.0.1", - "hamt-sharding": "^2.0.0", - "interface-blockstore": "^2.0.3", - "ipfs-unixfs": "^6.0.0", - "it-last": "^1.0.5", - "multiformats": "^9.4.2", - "uint8arrays": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs-exporter/node_modules/@ipld/dag-cbor": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz", - "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", - "dependencies": { - "cborg": "^1.6.0", - "multiformats": "^9.5.4" - } - }, - "node_modules/ipfs-unixfs-exporter/node_modules/interface-blockstore": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-2.0.3.tgz", - "integrity": "sha512-OwVUnlNcx7H5HloK0Myv6c/C1q9cNG11HX6afdeU6q6kbuNj8jKCwVnmJHhC94LZaJ+9hvVOk4IUstb3Esg81w==", - "dependencies": { - "interface-store": "^2.0.2", - "multiformats": "^9.0.4" - } - }, - "node_modules/ipfs-unixfs-exporter/node_modules/interface-store": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-2.0.2.tgz", - "integrity": "sha512-rScRlhDcz6k199EkHqT8NpM87ebN89ICOzILoBHgaG36/WX50N32BnU/kpZgCGPLhARRAWUUX5/cyaIjt7Kipg==" - }, - "node_modules/ipfs-unixfs-exporter/node_modules/multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - }, - "node_modules/ipfs-unixfs-importer": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-14.0.1.tgz", - "integrity": "sha512-ktsXRDC3AraX6Z3NbKREOcHlcYm0o4j2J7ygJLn3N1DpIbUPNmX5z3wl45DMH5b2HIZVqnS68VxKyr9H9LLhnw==", + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.4.tgz", + "integrity": "sha512-kcCUQXMw/2vJ9os6YxYWXpxmDPNwdg15xIM+pAjykBODFVUbo/9lgEZZTHXEj8t4ZTWn62LPjts5L8Tpv+wlKw==", "dependencies": { + "@ipld/dag-cbor": "^9.0.0", "@ipld/dag-pb": "^4.0.0", "@multiformats/murmur3": "^2.0.0", "err-code": "^3.0.1", "hamt-sharding": "^3.0.0", - "interface-blockstore": "^4.0.0", + "interface-blockstore": "^5.0.0", "ipfs-unixfs": "^11.0.0", - "it-all": "^2.0.0", - "it-batch": "^2.0.0", - "it-first": "^2.0.0", - "it-parallel-batch": "^2.0.0", + "it-filter": "^3.0.2", + "it-last": "^3.0.2", + "it-map": "^3.0.3", + "it-parallel": "^3.0.0", + "it-pipe": "^3.0.1", + "it-pushable": "^3.1.0", "multiformats": "^11.0.0", - "rabin-wasm": "^0.1.4", - "uint8arraylist": "^2.4.3", + "p-queue": "^7.3.0", + "progress-events": "^1.0.0", "uint8arrays": "^4.0.2" }, "engines": { @@ -4009,10 +3964,10 @@ "npm": ">=7.0.0" } }, - "node_modules/ipfs-unixfs-importer/node_modules/@ipld/dag-pb": { + "node_modules/ipfs-unixfs-exporter/node_modules/uint8arrays": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.3.tgz", - "integrity": "sha512-bOe+Z2ZJs9pmP/aIUBYMTdXq0i5z1x71qXeOIIhZvnKFLuzTIbbW0u5b7OfTGzUEbSv1dkUZBIXa7G/+OA8dnA==", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", + "integrity": "sha512-b+aKlI2oTnxnfeSQWV1sMacqSNxqhtXySaH6bflvONGxF8V/fT3ZlYH7z2qgGfydsvpVo4JUgM/Ylyfl2YouCg==", "dependencies": { "multiformats": "^11.0.0" }, @@ -4021,25 +3976,26 @@ "npm": ">=7.0.0" } }, - "node_modules/ipfs-unixfs-importer/node_modules/@multiformats/murmur3": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.3.tgz", - "integrity": "sha512-YvLK1IrLnRckPsvXhOkZjaIGNonsEdD1dL3NPSaLilV/WjVYeBgnNZXTUsaPzFXGrIFM7motx+yCmmqzXO6gtQ==", + "node_modules/ipfs-unixfs-importer": { + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.1.4.tgz", + "integrity": "sha512-j0Nzr9XOvXGehaUNw9NzzRHMDGK/cNzQyWrn+t+4RJZaJpqySV+goIqiuW9kH9HVPW4SYUhS4Oj5bctKK+vrdg==", "dependencies": { + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", + "err-code": "^3.0.1", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.1", + "ipfs-unixfs": "^11.0.0", + "it-all": "^3.0.2", + "it-batch": "^3.0.2", + "it-first": "^3.0.2", + "it-parallel-batch": "^3.0.1", "multiformats": "^11.0.0", - "murmurhash3js-revisited": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/ipfs-unixfs-importer/node_modules/hamt-sharding": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", - "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", - "dependencies": { - "sparse-array": "^1.3.1", + "progress-events": "^1.0.0", + "rabin-wasm": "^0.1.4", + "uint8arraylist": "^2.4.3", "uint8arrays": "^4.0.2" }, "engines": { @@ -4047,20 +4003,6 @@ "npm": ">=7.0.0" } }, - "node_modules/ipfs-unixfs-importer/node_modules/ipfs-unixfs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.0.0.tgz", - "integrity": "sha512-ZHTTzP5yuimLTln+8VKc3IcsO4ObS6/U8eZ3CA69s1DdW9uBfyjEo6/GTZA80yokHVGWvmCl1S28zmJ5JskP4Q==", - "dependencies": { - "err-code": "^3.0.1", - "protons-runtime": "^5.0.0", - "uint8arraylist": "^2.4.3" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - } - }, "node_modules/ipfs-unixfs-importer/node_modules/uint8arrays": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", @@ -4339,71 +4281,137 @@ } }, "node_modules/it-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-all/-/it-all-2.0.1.tgz", - "integrity": "sha512-9UuJcCRZsboz+HBQTNOau80Dw+ryGaHYFP/cPYzFBJBFcfDathMYnhHk4t52en9+fcyDGPTdLB+lFc1wzQIroA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-3.0.2.tgz", + "integrity": "sha512-ujqWETXhsDbF6C+6X6fvRw5ohlowRoy/o/h9BC8D+R3JQ13oLQ153w9gSWkWupOY7omZFQbJiAL1aJo5Gwe2yw==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, "node_modules/it-batch": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-2.0.1.tgz", - "integrity": "sha512-2gWFuPzamh9Dh3pW+OKjc7UwJ41W4Eu2AinVAfXDMfrC5gXfm3b1TF+1UzsygBUgKBugnxnGP+/fFRyn+9y1mQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.2.tgz", + "integrity": "sha512-Ypepz/vCxNFOvFkUPFvoxGb8WzqainzhflRaJahp1MBo3Y42ICdrgR3xIwOFE6WAgO+UWUM0zeMlbUStsW9AIQ==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/it-drain": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-drain/-/it-drain-2.0.1.tgz", - "integrity": "sha512-ESuHV6MLUNxuSy0vGZpKhSRjW0ixczN1FhbVy7eGJHjX6U2qiiXTyMvDc0z/w+nifOOwPyI5DT9Rc3o9IaGqEQ==", + "node_modules/it-filter": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.0.2.tgz", + "integrity": "sha512-Hhzp5anX7tmKOBqTPasBYTPlq7l4Xk4lMBfLB5GfKZnL9WCc6pr8M9Waud4nHh3s9neb4xwDWk7KQsEapgWyJw==", + "dependencies": { + "it-peekable": "^3.0.0" + }, "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/it-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-2.0.2.tgz", - "integrity": "sha512-gocw1F3siqupegsOzZ78rAc9C+sYlQbI2af/TmzgdrR613MyEJHbvfwBf12XRekGG907kqXSOGKPlxzJa6XV1Q==", + "node_modules/it-first": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.2.tgz", + "integrity": "sha512-QPLAM2BOkait/o6W25HvP0XTEv+Os3Ce4wET//ADNaPv+WYAHWfQwJuMu5FB8X066hA1F7LEMnULvTpE7/4yQw==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/it-first": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-first/-/it-first-2.0.1.tgz", - "integrity": "sha512-noC1oEQcWZZMUwq7VWxHNLML43dM+5bviZpfmkxkXlvBe60z7AFRqpZSga9uQBo792jKv9otnn1IjA4zwgNARw==", + "node_modules/it-last": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.2.tgz", + "integrity": "sha512-aWoA5moJ7XSKe7+YuutBKhySroDDWkfjpo+UknekPh1M5YYdK4YNSPDarR+7o/NqRwzazwgzCi2UZzU0oqsprQ==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/it-last": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/it-last/-/it-last-1.0.6.tgz", - "integrity": "sha512-aFGeibeiX/lM4bX3JY0OkVCFkAw8+n9lkukkLNivbJRvNz8lI3YXv5xcqhFUV2lDJiraEK3OXRDbGuevnnR67Q==" + "node_modules/it-map": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-map/-/it-map-3.0.3.tgz", + "integrity": "sha512-Yf89GJYeYUZb2NZzWkvFHm3IBXlxro74i2vGRmpf8BYau3BhlaS37ieDenJEdYzkTGJhL/EbM1jPPw/KGVVVIw==", + "dependencies": { + "it-peekable": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-merge": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.1.tgz", + "integrity": "sha512-I6hjU1ABO+k3xY1H6JtCSDXvUME88pxIXSgKeT4WI5rPYbQzpr98ldacVuG95WbjaJxKl6Qot6lUdxduLBQPHA==", + "dependencies": { + "it-pushable": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-parallel": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-parallel/-/it-parallel-3.0.3.tgz", + "integrity": "sha512-Q5KmdvERHCOLDcgKqrzQ+yiMCdG6H9h7ZL3Zjx/Tx9xhZy8txSKoy+EiCgWZFs0rfYvxJhk6UkOpKLzJ1zM9ZA==", + "dependencies": { + "p-defer": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } }, "node_modules/it-parallel-batch": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-2.0.1.tgz", - "integrity": "sha512-tXh567/JfDGJ90Zi//H9HkL7kY27ARp0jf2vu2jUI6PUVBWfsoT+gC4eT41/b4+wkJXSGgT8ZHnivAOlMfcNjA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.1.tgz", + "integrity": "sha512-4KTvYVYpCdrYUrAHSeH6o5hnHuDVHWzB8TztV/hdckUZzZIjbax4kVblmnzoYREX8Huj5+50irBu7b+c8jyKQg==", + "dependencies": { + "it-batch": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-peekable": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.1.tgz", + "integrity": "sha512-5zBfkf6e+YoxxWV0YDXMwdQKnc7eeTX6xo3WYPm/8dIoctIiDnddInRWOW+83W/8/76sbnpWqqsO4gSyXandeQ==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-pipe": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-pipe/-/it-pipe-3.0.1.tgz", + "integrity": "sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==", "dependencies": { - "it-batch": "^2.0.0" + "it-merge": "^3.0.0", + "it-pushable": "^3.1.2", + "it-stream-types": "^2.0.1" }, "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" } }, - "node_modules/it-take": { + "node_modules/it-pushable": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.1.3.tgz", + "integrity": "sha512-f50iQ85HISS6DaWCyrqf9QJ6G/kQtKIMf9xZkgZgyOvxEQDfn8OfYcLXXquCqgoLboxQtAW1ZFZyFIAsLHDtJw==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/it-stream-types": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-take/-/it-take-2.0.1.tgz", - "integrity": "sha512-DL7kpZNjuoeSTnB9dMAJ0Z3m2T29LRRAU+HIgkiQM+1jH3m8l9e/1xpWs8JHTlbKivbqSFrQMTc8KVcaQNmsaA==", + "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.1.tgz", + "integrity": "sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==", "engines": { "node": ">=16.0.0", "npm": ">=7.0.0" @@ -4957,9 +4965,9 @@ } }, "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/loupe": { "version": "2.3.6", @@ -5624,6 +5632,17 @@ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", "dev": true }, + "node_modules/p-defer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", + "integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5654,6 +5673,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.3.4.tgz", + "integrity": "sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg==", + "dependencies": { + "eventemitter3": "^4.0.7", + "p-timeout": "^5.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -5886,10 +5931,19 @@ "node": ">= 0.6.0" } }, + "node_modules/progress-events": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.0.tgz", + "integrity": "sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==", + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", + "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -5902,13 +5956,11 @@ "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", "@types/node": ">=13.7.0", - "long": "^4.0.0" + "long": "^5.0.0" }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" + "engines": { + "node": ">=12.0.0" } }, "node_modules/protons-runtime": { @@ -5927,34 +5979,6 @@ "uint8arraylist": "^2.3.2" } }, - "node_modules/protons-runtime/node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/protons-runtime/node_modules/protobufjs": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", - "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -7608,7 +7632,7 @@ "dependencies": { "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "cross-fetch": "3.1.5" }, "devDependencies": { @@ -7643,7 +7667,7 @@ "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@tbd54566975/web5-agent": "0.1.0", "@tbd54566975/web5-proxy-agent": "0.1.0", "@tbd54566975/web5-user-agent": "0.1.0", @@ -7683,8 +7707,8 @@ "name": "@tbd54566975/web5-agent", "version": "0.1.0", "dependencies": { - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", - "readable-stream": "4.3.0" + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", + "readable-stream": "4.4.0" }, "devDependencies": { "@types/eslint": "8.37.0", @@ -7696,6 +7720,20 @@ "typescript": "5.0.4" } }, + "packages/web5-agent/node_modules/readable-stream": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.0.tgz", + "integrity": "sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "packages/web5-proxy-agent": { "name": "@tbd54566975/web5-proxy-agent", "version": "0.1.0", @@ -7732,7 +7770,7 @@ "dependencies": { "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "abstract-level": "1.0.3", "cross-fetch": "3.1.5", "flat": "5.0.2", @@ -8884,18 +8922,11 @@ } }, "@ipld/dag-pb": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-2.1.18.tgz", - "integrity": "sha512-ZBnf2fuX9y3KccADURG5vb9FaOeMjFkCrNysB0PtftME/4iCTjxfaLoNq/IAh5fTqUOMXvryN6Jyka4ZGuMLIg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.3.tgz", + "integrity": "sha512-bOe+Z2ZJs9pmP/aIUBYMTdXq0i5z1x71qXeOIIhZvnKFLuzTIbbW0u5b7OfTGzUEbSv1dkUZBIXa7G/+OA8dnA==", "requires": { - "multiformats": "^9.5.4" - }, - "dependencies": { - "multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - } + "multiformats": "^11.0.0" } }, "@jridgewell/gen-mapping": { @@ -8968,19 +8999,12 @@ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, "@multiformats/murmur3": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-1.1.3.tgz", - "integrity": "sha512-wAPLUErGR8g6Lt+bAZn6218k9YQPym+sjszsXL6o4zfxbA22P+gxWZuuD9wDbwL55xrKO5idpcuQUX7/E3oHcw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.3.tgz", + "integrity": "sha512-YvLK1IrLnRckPsvXhOkZjaIGNonsEdD1dL3NPSaLilV/WjVYeBgnNZXTUsaPzFXGrIFM7motx+yCmmqzXO6gtQ==", "requires": { - "multiformats": "^9.5.4", + "multiformats": "^11.0.0", "murmurhash3js-revisited": "^3.0.0" - }, - "dependencies": { - "multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" - } } }, "@noble/ed25519": { @@ -9196,7 +9220,7 @@ "requires": { "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@types/chai": "4.3.0", "@types/eslint": "8.37.0", "@types/mocha": "10.0.1", @@ -9222,9 +9246,9 @@ } }, "@tbd54566975/dwn-sdk-js": { - "version": "0.0.31-unstable-2023-05-11-32b5f91", - "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.0.31-unstable-2023-05-11-32b5f91.tgz", - "integrity": "sha512-MV3AFCy0kCAd1phAzyr1RvaGB74i9V5jFusVQ8YJGJ+unuQW/AYc33ZTAoBdhsxon3TuXeWpiAFS0OWSwCjEQw==", + "version": "0.0.32-unstable-2023-05-15-1350300", + "resolved": "https://registry.npmjs.org/@tbd54566975/dwn-sdk-js/-/dwn-sdk-js-0.0.32-unstable-2023-05-15-1350300.tgz", + "integrity": "sha512-ymPmSwfiXv+4G2nGet87RjBA1Xun7V7jIo6YZnNPIFqw+vbn9sMj1ikuydRrlvW1cE2eCznuE8fTzEoe4trcLQ==", "requires": { "@ipld/dag-cbor": "9.0.0", "@js-temporal/polyfill": "0.4.3", @@ -9239,15 +9263,15 @@ "@types/secp256k1": "4.0.3", "abstract-level": "1.0.3", "ajv": "8.12.0", - "blockstore-core": "3.0.0", + "blockstore-core": "4.1.0", "cross-fetch": "3.1.5", "date-fns": "2.28.0", "eccrypto": "1.1.6", "flat": "^5.0.2", - "interface-blockstore": "4.0.1", - "ipfs-unixfs": "6.0.9", - "ipfs-unixfs-exporter": "7.0.11", - "ipfs-unixfs-importer": "14.0.1", + "interface-blockstore": "5.2.0", + "interface-store": "^5.1.0", + "ipfs-unixfs-exporter": "13.1.4", + "ipfs-unixfs-importer": "15.1.4", "level": "8.0.0", "lodash": "4.17.21", "lru-cache": "7.12.0", @@ -9284,7 +9308,7 @@ "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@tbd54566975/web5-agent": "0.1.0", "@tbd54566975/web5-proxy-agent": "0.1.0", "@tbd54566975/web5-user-agent": "0.1.0", @@ -9507,15 +9531,28 @@ "@tbd54566975/web5-agent": { "version": "file:packages/web5-agent", "requires": { - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@types/eslint": "8.37.0", "@typescript-eslint/eslint-plugin": "5.59.0", "@typescript-eslint/parser": "5.59.0", "esbuild": "0.16.7", "eslint": "8.39.0", - "readable-stream": "4.3.0", + "readable-stream": "4.4.0", "rimraf": "4.4.0", "typescript": "5.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.0.tgz", + "integrity": "sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg==", + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + } + } } }, "@tbd54566975/web5-proxy-agent": { @@ -9550,7 +9587,7 @@ "@decentralized-identity/ion-tools": "1.0.7", "@playwright/test": "^1.33.0", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@types/flat": "5.0.2", "@typescript-eslint/eslint-plugin": "5.59.0", "@typescript-eslint/parser": "5.59.0", @@ -9859,11 +9896,6 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, "@types/mocha": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", @@ -10381,18 +10413,14 @@ } }, "blockstore-core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-3.0.0.tgz", - "integrity": "sha512-5ZZB5nh6kErcjZ/CTK6lCwTIGlPdkTXbD8+2xLC4Fm0WGh7g2e2lW2bfURw7mvnPtSX1xV+sN4V2ndowSgIiHQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/blockstore-core/-/blockstore-core-4.1.0.tgz", + "integrity": "sha512-CxlavQ6Yri8Se/l7F6ug8AK9StcJK42UdnJQua3XlwoQUVGSuIRnY+q2wqFzuCAuv4m4a5pp/JH29GliV4EEgQ==", "requires": { "err-code": "^3.0.1", - "interface-blockstore": "^4.0.0", - "interface-store": "^3.0.0", - "it-all": "^2.0.0", - "it-drain": "^2.0.0", - "it-filter": "^2.0.0", - "it-take": "^2.0.0", - "multiformats": "^11.0.0" + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" } }, "bn.js": { @@ -11496,8 +11524,7 @@ "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "events": { "version": "3.3.0", @@ -11820,12 +11847,22 @@ "dev": true }, "hamt-sharding": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-2.0.1.tgz", - "integrity": "sha512-vnjrmdXG9dDs1m/H4iJ6z0JFI2NtgsW5keRkTcM85NGak69Mkf5PHUqBz+Xs0T4sg0ppvj9O5EGAJo40FTxmmA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", + "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", "requires": { "sparse-array": "^1.3.1", - "uint8arrays": "^3.0.0" + "uint8arrays": "^4.0.2" + }, + "dependencies": { + "uint8arrays": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", + "integrity": "sha512-b+aKlI2oTnxnfeSQWV1sMacqSNxqhtXySaH6bflvONGxF8V/fT3ZlYH7z2qgGfydsvpVo4JUgM/Ylyfl2YouCg==", + "requires": { + "multiformats": "^11.0.0" + } + } } }, "has": { @@ -12017,132 +12054,86 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "interface-blockstore": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-4.0.1.tgz", - "integrity": "sha512-ROWKGJls7vLeFaQtI3hZVCJOkUoZ05xAi2t2qysM4d7dwVKrfm5jUOqWh8JgLL7Iup3XqJ0mKXXZuwJ3s03RSw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.2.0.tgz", + "integrity": "sha512-lLW6fNP3PkBKghK9BsLuV8VMquL/o2lInomrTUizY/p4n7vxzVn3YT7qGTHywZzCcMIBeGMneDApGe21TNkg+g==", "requires": { - "interface-store": "^3.0.0", - "multiformats": "^11.0.0" + "interface-store": "^5.0.0", + "multiformats": "^11.0.2" } }, "interface-store": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-3.0.4.tgz", - "integrity": "sha512-OjHUuGXbH4eXSBx1TF1tTySvjLldPLzRSYYXJwrEQI+XfH5JWYZofr0gVMV4F8XTwC+4V7jomDYkvGRmDSRKqQ==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-5.1.0.tgz", + "integrity": "sha512-mjUwX3XSoreoxCS3sXS3pSRsGnUjl9T06KBqt/T7AgE9Sgp4diH64ZyURJKnj2T5WmCvTbC0Dm+mwQV5hfLSBQ==" }, "ipfs-unixfs": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-6.0.9.tgz", - "integrity": "sha512-0DQ7p0/9dRB6XCb0mVCTli33GzIzSVx5udpJuVM47tGcD+W+Bl4LsnoLswd3ggNnNEakMv1FdoFITiEnchXDqQ==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.0.1.tgz", + "integrity": "sha512-SD9dqn14bfgMfkPstsR/2Av3zCzYMj2ntQJab4HZucgX4nNV6K7guZh4Hf3kiL8ONff1Ogft1ekFU083DIKEdQ==", "requires": { "err-code": "^3.0.1", - "protobufjs": "^6.10.2" + "protons-runtime": "^5.0.0", + "uint8arraylist": "^2.4.3" } }, "ipfs-unixfs-exporter": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-7.0.11.tgz", - "integrity": "sha512-qTYa69J7HbI2EIYNUddKPg9Y3rHkYZV0bNdmzZKA5+ZbwRVoUEuBW/cguEqTp22zHygh3sMnzYZFm0naVIdMgQ==", + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.1.4.tgz", + "integrity": "sha512-kcCUQXMw/2vJ9os6YxYWXpxmDPNwdg15xIM+pAjykBODFVUbo/9lgEZZTHXEj8t4ZTWn62LPjts5L8Tpv+wlKw==", "requires": { - "@ipld/dag-cbor": "^7.0.2", - "@ipld/dag-pb": "^2.0.2", - "@multiformats/murmur3": "^1.0.3", + "@ipld/dag-cbor": "^9.0.0", + "@ipld/dag-pb": "^4.0.0", + "@multiformats/murmur3": "^2.0.0", "err-code": "^3.0.1", - "hamt-sharding": "^2.0.0", - "interface-blockstore": "^2.0.3", - "ipfs-unixfs": "^6.0.0", - "it-last": "^1.0.5", - "multiformats": "^9.4.2", - "uint8arrays": "^3.0.0" - }, - "dependencies": { - "@ipld/dag-cbor": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-7.0.3.tgz", - "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", - "requires": { - "cborg": "^1.6.0", - "multiformats": "^9.5.4" - } - }, - "interface-blockstore": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-2.0.3.tgz", - "integrity": "sha512-OwVUnlNcx7H5HloK0Myv6c/C1q9cNG11HX6afdeU6q6kbuNj8jKCwVnmJHhC94LZaJ+9hvVOk4IUstb3Esg81w==", + "hamt-sharding": "^3.0.0", + "interface-blockstore": "^5.0.0", + "ipfs-unixfs": "^11.0.0", + "it-filter": "^3.0.2", + "it-last": "^3.0.2", + "it-map": "^3.0.3", + "it-parallel": "^3.0.0", + "it-pipe": "^3.0.1", + "it-pushable": "^3.1.0", + "multiformats": "^11.0.0", + "p-queue": "^7.3.0", + "progress-events": "^1.0.0", + "uint8arrays": "^4.0.2" + }, + "dependencies": { + "uint8arrays": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", + "integrity": "sha512-b+aKlI2oTnxnfeSQWV1sMacqSNxqhtXySaH6bflvONGxF8V/fT3ZlYH7z2qgGfydsvpVo4JUgM/Ylyfl2YouCg==", "requires": { - "interface-store": "^2.0.2", - "multiformats": "^9.0.4" + "multiformats": "^11.0.0" } - }, - "interface-store": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-2.0.2.tgz", - "integrity": "sha512-rScRlhDcz6k199EkHqT8NpM87ebN89ICOzILoBHgaG36/WX50N32BnU/kpZgCGPLhARRAWUUX5/cyaIjt7Kipg==" - }, - "multiformats": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", - "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" } } }, "ipfs-unixfs-importer": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-14.0.1.tgz", - "integrity": "sha512-ktsXRDC3AraX6Z3NbKREOcHlcYm0o4j2J7ygJLn3N1DpIbUPNmX5z3wl45DMH5b2HIZVqnS68VxKyr9H9LLhnw==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-15.1.4.tgz", + "integrity": "sha512-j0Nzr9XOvXGehaUNw9NzzRHMDGK/cNzQyWrn+t+4RJZaJpqySV+goIqiuW9kH9HVPW4SYUhS4Oj5bctKK+vrdg==", "requires": { "@ipld/dag-pb": "^4.0.0", "@multiformats/murmur3": "^2.0.0", "err-code": "^3.0.1", "hamt-sharding": "^3.0.0", - "interface-blockstore": "^4.0.0", + "interface-blockstore": "^5.0.0", + "interface-store": "^5.0.1", "ipfs-unixfs": "^11.0.0", - "it-all": "^2.0.0", - "it-batch": "^2.0.0", - "it-first": "^2.0.0", - "it-parallel-batch": "^2.0.0", + "it-all": "^3.0.2", + "it-batch": "^3.0.2", + "it-first": "^3.0.2", + "it-parallel-batch": "^3.0.1", "multiformats": "^11.0.0", + "progress-events": "^1.0.0", "rabin-wasm": "^0.1.4", "uint8arraylist": "^2.4.3", "uint8arrays": "^4.0.2" }, "dependencies": { - "@ipld/dag-pb": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.0.3.tgz", - "integrity": "sha512-bOe+Z2ZJs9pmP/aIUBYMTdXq0i5z1x71qXeOIIhZvnKFLuzTIbbW0u5b7OfTGzUEbSv1dkUZBIXa7G/+OA8dnA==", - "requires": { - "multiformats": "^11.0.0" - } - }, - "@multiformats/murmur3": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.3.tgz", - "integrity": "sha512-YvLK1IrLnRckPsvXhOkZjaIGNonsEdD1dL3NPSaLilV/WjVYeBgnNZXTUsaPzFXGrIFM7motx+yCmmqzXO6gtQ==", - "requires": { - "multiformats": "^11.0.0", - "murmurhash3js-revisited": "^3.0.0" - } - }, - "hamt-sharding": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.2.tgz", - "integrity": "sha512-f0DzBD2tSmLFdFsLAvOflIBqFPjerbA7BfmwO8mVho/5hXwgyyYhv+ijIzidQf/DpDX3bRjAQvhGoBFj+DBvPw==", - "requires": { - "sparse-array": "^1.3.1", - "uint8arrays": "^4.0.2" - } - }, - "ipfs-unixfs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.0.0.tgz", - "integrity": "sha512-ZHTTzP5yuimLTln+8VKc3IcsO4ObS6/U8eZ3CA69s1DdW9uBfyjEo6/GTZA80yokHVGWvmCl1S28zmJ5JskP4Q==", - "requires": { - "err-code": "^3.0.1", - "protons-runtime": "^5.0.0", - "uint8arraylist": "^2.4.3" - } - }, "uint8arrays": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-4.0.3.tgz", @@ -12318,47 +12309,89 @@ "dev": true }, "it-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-all/-/it-all-2.0.1.tgz", - "integrity": "sha512-9UuJcCRZsboz+HBQTNOau80Dw+ryGaHYFP/cPYzFBJBFcfDathMYnhHk4t52en9+fcyDGPTdLB+lFc1wzQIroA==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-all/-/it-all-3.0.2.tgz", + "integrity": "sha512-ujqWETXhsDbF6C+6X6fvRw5ohlowRoy/o/h9BC8D+R3JQ13oLQ153w9gSWkWupOY7omZFQbJiAL1aJo5Gwe2yw==" }, "it-batch": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-2.0.1.tgz", - "integrity": "sha512-2gWFuPzamh9Dh3pW+OKjc7UwJ41W4Eu2AinVAfXDMfrC5gXfm3b1TF+1UzsygBUgKBugnxnGP+/fFRyn+9y1mQ==" - }, - "it-drain": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-drain/-/it-drain-2.0.1.tgz", - "integrity": "sha512-ESuHV6MLUNxuSy0vGZpKhSRjW0ixczN1FhbVy7eGJHjX6U2qiiXTyMvDc0z/w+nifOOwPyI5DT9Rc3o9IaGqEQ==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-batch/-/it-batch-3.0.2.tgz", + "integrity": "sha512-Ypepz/vCxNFOvFkUPFvoxGb8WzqainzhflRaJahp1MBo3Y42ICdrgR3xIwOFE6WAgO+UWUM0zeMlbUStsW9AIQ==" }, "it-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-2.0.2.tgz", - "integrity": "sha512-gocw1F3siqupegsOzZ78rAc9C+sYlQbI2af/TmzgdrR613MyEJHbvfwBf12XRekGG907kqXSOGKPlxzJa6XV1Q==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.0.2.tgz", + "integrity": "sha512-Hhzp5anX7tmKOBqTPasBYTPlq7l4Xk4lMBfLB5GfKZnL9WCc6pr8M9Waud4nHh3s9neb4xwDWk7KQsEapgWyJw==", + "requires": { + "it-peekable": "^3.0.0" + } }, "it-first": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-first/-/it-first-2.0.1.tgz", - "integrity": "sha512-noC1oEQcWZZMUwq7VWxHNLML43dM+5bviZpfmkxkXlvBe60z7AFRqpZSga9uQBo792jKv9otnn1IjA4zwgNARw==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.2.tgz", + "integrity": "sha512-QPLAM2BOkait/o6W25HvP0XTEv+Os3Ce4wET//ADNaPv+WYAHWfQwJuMu5FB8X066hA1F7LEMnULvTpE7/4yQw==" }, "it-last": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/it-last/-/it-last-1.0.6.tgz", - "integrity": "sha512-aFGeibeiX/lM4bX3JY0OkVCFkAw8+n9lkukkLNivbJRvNz8lI3YXv5xcqhFUV2lDJiraEK3OXRDbGuevnnR67Q==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.2.tgz", + "integrity": "sha512-aWoA5moJ7XSKe7+YuutBKhySroDDWkfjpo+UknekPh1M5YYdK4YNSPDarR+7o/NqRwzazwgzCi2UZzU0oqsprQ==" + }, + "it-map": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-map/-/it-map-3.0.3.tgz", + "integrity": "sha512-Yf89GJYeYUZb2NZzWkvFHm3IBXlxro74i2vGRmpf8BYau3BhlaS37ieDenJEdYzkTGJhL/EbM1jPPw/KGVVVIw==", + "requires": { + "it-peekable": "^3.0.0" + } + }, + "it-merge": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.1.tgz", + "integrity": "sha512-I6hjU1ABO+k3xY1H6JtCSDXvUME88pxIXSgKeT4WI5rPYbQzpr98ldacVuG95WbjaJxKl6Qot6lUdxduLBQPHA==", + "requires": { + "it-pushable": "^3.1.0" + } + }, + "it-parallel": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/it-parallel/-/it-parallel-3.0.3.tgz", + "integrity": "sha512-Q5KmdvERHCOLDcgKqrzQ+yiMCdG6H9h7ZL3Zjx/Tx9xhZy8txSKoy+EiCgWZFs0rfYvxJhk6UkOpKLzJ1zM9ZA==", + "requires": { + "p-defer": "^4.0.0" + } }, "it-parallel-batch": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-2.0.1.tgz", - "integrity": "sha512-tXh567/JfDGJ90Zi//H9HkL7kY27ARp0jf2vu2jUI6PUVBWfsoT+gC4eT41/b4+wkJXSGgT8ZHnivAOlMfcNjA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-parallel-batch/-/it-parallel-batch-3.0.1.tgz", + "integrity": "sha512-4KTvYVYpCdrYUrAHSeH6o5hnHuDVHWzB8TztV/hdckUZzZIjbax4kVblmnzoYREX8Huj5+50irBu7b+c8jyKQg==", + "requires": { + "it-batch": "^3.0.0" + } + }, + "it-peekable": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.1.tgz", + "integrity": "sha512-5zBfkf6e+YoxxWV0YDXMwdQKnc7eeTX6xo3WYPm/8dIoctIiDnddInRWOW+83W/8/76sbnpWqqsO4gSyXandeQ==" + }, + "it-pipe": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/it-pipe/-/it-pipe-3.0.1.tgz", + "integrity": "sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==", "requires": { - "it-batch": "^2.0.0" + "it-merge": "^3.0.0", + "it-pushable": "^3.1.2", + "it-stream-types": "^2.0.1" } }, - "it-take": { + "it-pushable": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.1.3.tgz", + "integrity": "sha512-f50iQ85HISS6DaWCyrqf9QJ6G/kQtKIMf9xZkgZgyOvxEQDfn8OfYcLXXquCqgoLboxQtAW1ZFZyFIAsLHDtJw==" + }, + "it-stream-types": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/it-take/-/it-take-2.0.1.tgz", - "integrity": "sha512-DL7kpZNjuoeSTnB9dMAJ0Z3m2T29LRRAU+HIgkiQM+1jH3m8l9e/1xpWs8JHTlbKivbqSFrQMTc8KVcaQNmsaA==" + "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.1.tgz", + "integrity": "sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==" }, "jest-worker": { "version": "27.5.1", @@ -12803,9 +12836,9 @@ } }, "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "loupe": { "version": "2.3.6", @@ -13317,6 +13350,11 @@ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", "dev": true }, + "p-defer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", + "integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==" + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -13335,6 +13373,20 @@ "p-limit": "^3.0.2" } }, + "p-queue": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.3.4.tgz", + "integrity": "sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg==", + "requires": { + "eventemitter3": "^4.0.7", + "p-timeout": "^5.0.2" + } + }, + "p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==" + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -13505,10 +13557,15 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" }, + "progress-events": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.0.tgz", + "integrity": "sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==" + }, "protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", + "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -13520,9 +13577,8 @@ "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", "@types/node": ">=13.7.0", - "long": "^4.0.0" + "long": "^5.0.0" } }, "protons-runtime": { @@ -13532,32 +13588,6 @@ "requires": { "protobufjs": "^7.0.0", "uint8arraylist": "^2.4.3" - }, - "dependencies": { - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "protobufjs": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", - "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - } } }, "public-encrypt": { diff --git a/packages/dids/package.json b/packages/dids/package.json index d323df58d..f402e2d6f 100644 --- a/packages/dids/package.json +++ b/packages/dids/package.json @@ -25,7 +25,7 @@ "dependencies": { "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "cross-fetch": "3.1.5" }, "devDependencies": { diff --git a/packages/web5-agent/package.json b/packages/web5-agent/package.json index 772a0c39d..96e911c73 100644 --- a/packages/web5-agent/package.json +++ b/packages/web5-agent/package.json @@ -27,8 +27,8 @@ "lint:fix": "eslint . --ext .js --fix" }, "dependencies": { - "readable-stream": "4.3.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91" + "readable-stream": "4.4.0", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "5.59.0", diff --git a/packages/web5-agent/src/web5-agent.ts b/packages/web5-agent/src/web5-agent.ts index 4ee9610b0..48db77780 100644 --- a/packages/web5-agent/src/web5-agent.ts +++ b/packages/web5-agent/src/web5-agent.ts @@ -1,6 +1,6 @@ import type { Readable } from 'readable-stream'; -import type { +import { MessageReply, RecordsQueryMessage, ProtocolsQueryMessage, @@ -13,8 +13,8 @@ import type { import type { JsonRpcResponse } from './json-rpc.js'; export interface Web5Agent { - processDwnRequest(request: ProcessDwnRequest): Promise - sendDwnRequest(request: ProcessDwnRequest): Promise; + processDwnRequest(request: ProcessDwnRequest): Promise + sendDwnRequest(request: SendDwnRequest): Promise; } export type DwnMessages = { @@ -29,33 +29,29 @@ export type DwnMessages = { export type DwnMessageType = keyof DwnMessages; -/** - * TODO: add JSDoc - */ -export type ProcessDwnRequest = { +export type DwnRequest = { author: string; - dataStream?: Blob | ReadableStream | Readable; - messageType: string; - messageOptions: unknown; target: string; + messageType: string; } /** * TODO: add JSDoc */ -export type ProcessDwnResponse = { - message?: unknown; - reply: MessageReply; +export type ProcessDwnRequest = DwnRequest & { + dataStream?: Blob | ReadableStream | Readable; + messageOptions: unknown; }; +export type SendDwnRequest = DwnRequest & (ProcessDwnRequest | { messageCid: string }) + /** * TODO: add JSDoc */ -export type SendDwnRequest = { - author: string; - messageCid: string; - messageType: string; - target: string; +export type DwnResponse = { + message?: unknown; + messageCid?: string; + reply: MessageReply; }; diff --git a/packages/web5-proxy-agent/src/web5-proxy-agent.ts b/packages/web5-proxy-agent/src/web5-proxy-agent.ts index eba646160..3182530d4 100644 --- a/packages/web5-proxy-agent/src/web5-proxy-agent.ts +++ b/packages/web5-proxy-agent/src/web5-proxy-agent.ts @@ -1,15 +1,15 @@ -import type { ProcessDwnRequest, ProcessDwnResponse, SendDwnRequest, Web5Agent } from '@tbd54566975/web5-agent'; +import type { DwnRequest, DwnResponse, Web5Agent } from '@tbd54566975/web5-agent'; // TODO: concretely define json-rpc types specific to each Web5Agent interface method // TODO: write http transport. that transport will be shareable with client for dwn-server // TODO: write ws transport. that transport will be shareable with client for dwn-server // TODO: figure out where to put DidConnect. export class Web5ProxyAgent implements Web5Agent { - processDwnRequest(_request: ProcessDwnRequest): Promise { + processDwnRequest(_request: DwnRequest): Promise { throw new Error('Method not implemented.'); } - sendDwnRequest(_request: ProcessDwnRequest): Promise { + sendDwnRequest(_request: DwnRequest): Promise { throw new Error('Method not implemented.'); } } \ No newline at end of file diff --git a/packages/web5-user-agent/.mocharc.json b/packages/web5-user-agent/.mocharc.json new file mode 100644 index 000000000..2e8b2e076 --- /dev/null +++ b/packages/web5-user-agent/.mocharc.json @@ -0,0 +1,3 @@ +{ + "enable-source-maps": true +} \ No newline at end of file diff --git a/packages/web5-user-agent/karma.conf.cjs b/packages/web5-user-agent/karma.conf.cjs index 5f81b798d..11a39f81a 100644 --- a/packages/web5-user-agent/karma.conf.cjs +++ b/packages/web5-user-agent/karma.conf.cjs @@ -34,14 +34,14 @@ module.exports = function (config) { // list of files / patterns to load in the browser files: [ // { pattern: 'tests/test-user-agent.ts', watched: false }, - { pattern: 'tests/**/*.spec.ts', watched: false }, + { pattern: 'tests/common/**/*.spec.ts', watched: false }, ], // preprocess matching files before serving them to the browser // available preprocessors: https://www.npmjs.com/search?q=keywords:karma-preprocessor preprocessors: { // 'tests/test-user-agent.ts' : ['esbuild'], - 'tests/**/*.spec.ts': ['esbuild'], + 'tests/common/**/*.spec.ts': ['esbuild'], }, esbuild: esbuildBrowserConfig, diff --git a/packages/web5-user-agent/package.json b/packages/web5-user-agent/package.json index 053aa37a2..dee740427 100644 --- a/packages/web5-user-agent/package.json +++ b/packages/web5-user-agent/package.json @@ -54,7 +54,7 @@ "dependencies": { "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "abstract-level": "1.0.3", "cross-fetch": "3.1.5", "flat": "5.0.2", diff --git a/packages/web5-user-agent/src/dwn-rpc-client.ts b/packages/web5-user-agent/src/dwn-rpc-client.ts index 27907874e..142301889 100644 --- a/packages/web5-user-agent/src/dwn-rpc-client.ts +++ b/packages/web5-user-agent/src/dwn-rpc-client.ts @@ -1,28 +1,10 @@ -import { DwnRpc, DwnRpcRequest, DwnRpcResponse, createJsonRpcErrorResponse } from '@tbd54566975/web5-agent'; - -import crossFetch from 'cross-fetch'; +import type { DwnRpc, DwnRpcRequest, DwnRpcResponse, JsonRpcResponse } from '@tbd54566975/web5-agent'; import { v4 as uuidv4 } from 'uuid'; -import { JsonRpcResponse, createJsonRpcRequest, parseJson, JsonRpcErrorCodes } from '@tbd54566975/web5-agent'; +import { createJsonRpcRequest, parseJson } from '@tbd54566975/web5-agent'; // TODO: move what's below to dwn-server repo. i wrote this here for expediency -/** - * Supports fetch in: browser, browser extensions, Node, and React Native. - * In node, it uses node-fetch, and in a browser or React Native, it uses - * Github's whatwg-fetch. - * - * WARNING for browser extension background service workers: - * 'cross-fetch' is a ponyfill that uses `XMLHTTPRequest` under the hood. - * `XMLHTTPRequest` cannot be used in browser extension background service - * workers. Browser extensions get even more strict with `fetch` in that it - * cannot be referenced indirectly. - * - * use presence of File to decide whether we're in the browser or not - * TODO: ask Adam or Tim if globalThis is available in react native - */ -const fetch = globalThis.File ? globalThis.fetch : crossFetch; - /** * Client used to communicate with Dwn Servers */ @@ -89,16 +71,12 @@ class HttpDwnRpcClient implements DwnRpc { fetchOpts.headers['content-type'] = 'application/octet-stream'; fetchOpts['body'] = request.data; } - let resp; - try { - resp = await fetch(request.dwnUrl, fetchOpts); - } catch(e) { - return createJsonRpcErrorResponse(requestId, JsonRpcErrorCodes.TransportError, e.message); - } + const resp = await fetch(request.dwnUrl, fetchOpts); let dwnRpcResponse: DwnRpcResponse; // check to see if response is in header first. if it is, that means the response is a ReadableStream + let dataStream; const { headers } = resp; if (headers.has('dwn-response')) { const jsonRpcResponse = parseJson(headers.get('dwn-response')) as JsonRpcResponse; @@ -107,15 +85,23 @@ class HttpDwnRpcClient implements DwnRpc { throw new Error(`failed to parse json rpc response. dwn url: ${request.dwnUrl}`); } - dwnRpcResponse = { - ...jsonRpcResponse, - dataStream: resp.body - }; + dataStream = resp.body; + dwnRpcResponse = jsonRpcResponse; } else { // TODO: wonder if i need to try/catch this? dwnRpcResponse = await resp.json() as JsonRpcResponse; } - return dwnRpcResponse; + if (dwnRpcResponse.error) { + const { code, message } = dwnRpcResponse.error; + throw new Error(`(${code}) - ${message}`); + } + + const { reply } = dwnRpcResponse.result; + if (dataStream) { + reply['record']['data'] = dataStream; + } + + return reply; } } \ No newline at end of file diff --git a/packages/web5-user-agent/src/utils.ts b/packages/web5-user-agent/src/utils.ts index 9aad0085a..5659fedf1 100644 --- a/packages/web5-user-agent/src/utils.ts +++ b/packages/web5-user-agent/src/utils.ts @@ -2,5 +2,9 @@ import type { Readable } from 'readable-stream'; import { ReadableWebToNodeStream } from 'readable-web-to-node-stream'; export function blobToIsomorphicNodeReadable(blob: Blob): Readable { - return new ReadableWebToNodeStream(blob.stream()); + return webReadableToIsomorphicNodeReadable(blob.stream()); +} + +export function webReadableToIsomorphicNodeReadable(webReadable: ReadableStream) { + return new ReadableWebToNodeStream(webReadable); } \ No newline at end of file diff --git a/packages/web5-user-agent/src/web5-user-agent.ts b/packages/web5-user-agent/src/web5-user-agent.ts index cebc3c447..255f06d05 100644 --- a/packages/web5-user-agent/src/web5-user-agent.ts +++ b/packages/web5-user-agent/src/web5-user-agent.ts @@ -1,21 +1,28 @@ import type { DwnServiceEndpoint } from '@tbd54566975/dids'; +import { + SignatureInput, + RecordsWriteOptions, + RecordsWriteMessage, + PrivateJwk as DwnPrivateKeyJwk, + MessagesGetReply, + DataStream, + RecordsReadReply, +} from '@tbd54566975/dwn-sdk-js'; import { Readable } from 'readable-stream'; import { DwnRpc, Web5Agent, DwnRpcRequest, - DwnRpcResponse, - JsonRpcErrorCodes, ProcessDwnRequest, - ProcessDwnResponse, + DwnResponse, + SendDwnRequest, } from '@tbd54566975/web5-agent'; import { Cid, - SignatureInput, - RecordsWriteOptions, - PrivateJwk as DwnPrivateKeyJwk, + Encoder, + Message } from '@tbd54566975/dwn-sdk-js'; import type { ProfileManager } from './profile-manager.js'; @@ -37,7 +44,7 @@ import { import { ProfileApi } from './profile-api.js'; import { DwnRpcClient } from './dwn-rpc-client.js'; -import { blobToIsomorphicNodeReadable } from './utils.js'; +import { blobToIsomorphicNodeReadable, webReadableToIsomorphicNodeReadable } from './utils.js'; // TODO: allow user to provide optional array of DwnRpc implementations once DwnRpc has been moved out of this package export type Web5UserAgentOptions = { @@ -46,6 +53,11 @@ export type Web5UserAgentOptions = { didResolver: DidResolver; }; +type DwnMessage = { + message: any; + data?: Blob; +} + const dwnMessageCreators = { [DwnInterfaceName.Events + DwnMethodName.Get] : EventsGet, [DwnInterfaceName.Messages + DwnMethodName.Get] : MessagesGet, @@ -57,8 +69,6 @@ const dwnMessageCreators = { [DwnInterfaceName.Protocols + DwnMethodName.Configure] : ProtocolsConfigure, }; -const sendRetryCodes = new Set([JsonRpcErrorCodes.InternalError, JsonRpcErrorCodes.TransportError]); - export class Web5UserAgent implements Web5Agent { private dwn: Dwn; private profileManager: ProfileManager; @@ -91,31 +101,37 @@ export class Web5UserAgent implements Web5Agent { * @param message * @returns */ - async processDwnRequest(request: ProcessDwnRequest): Promise { - const dwnMessage = await this.#constructDwnMessage(request); - - let dataStream = request.dataStream; - if (request?.dataStream instanceof Blob) { - dataStream = blobToIsomorphicNodeReadable(request.dataStream); - } - - const reply = await this.dwn.processMessage(request.target, dwnMessage.toJSON(), dataStream as any); + async processDwnRequest(request: ProcessDwnRequest): Promise { + const { message, dataStream }= await this.#constructDwnMessage(request); + const reply = await this.dwn.processMessage(request.target, message, dataStream as any); return { reply, - message: dwnMessage.toJSON() + message : message, + messageCid : await Message.getCid(message) }; } - async sendDwnRequest(request: ProcessDwnRequest): Promise { - const dwnMessage = await this.#constructDwnMessage(request); - const dwnRpcRequest: Partial = { - targetDid : request.target, - message : dwnMessage - }; + async sendDwnRequest(request: SendDwnRequest): Promise { + const dwnRpcRequest: Partial = { targetDid: request.target }; + let messageData; - const didResolution = await this.didResolver.resolve(request.target); + if ('messageCid' in request) { + const { message, data } = await this.#getDwnMessage(request.author, request.messageType, request.messageCid); + + dwnRpcRequest.message = message; + messageData = data; + } else { + const { message } = await this.#constructDwnMessage(request); + dwnRpcRequest.message = message; + messageData = request.dataStream; + } + + if (messageData) { + dwnRpcRequest.data = messageData; + } + const didResolution = await this.didResolver.resolve(request.target); if (!didResolution.didDocument) { if (didResolution.didResolutionMetadata?.error) { throw new Error(`DID resolution error: ${didResolution.didResolutionMetadata.error}`); @@ -135,147 +151,110 @@ export class Web5UserAgent implements Web5Agent { } const { nodes } = serviceEndpoint as DwnServiceEndpoint; - let lastDwnRpcResponse: DwnRpcResponse; + let dwnReply; + let errorMessages = []; // try sending to author's publicly addressable dwn's until first request succeeds. for (let node of nodes) { dwnRpcRequest.dwnUrl = node; - lastDwnRpcResponse = await this.dwnRpcClient.sendDwnRequest(dwnRpcRequest as DwnRpcRequest); - if (lastDwnRpcResponse.error) { - const { error } = lastDwnRpcResponse; - if (sendRetryCodes.has(error.code)) { - continue; - } else { - break; - } - } else { + try { + dwnReply = await this.dwnRpcClient.sendDwnRequest(dwnRpcRequest as DwnRpcRequest); break; + } catch(e) { + errorMessages.push({ url: node, message: e.message }); } } - //! (Moe -> Frank) i think we're going to have to go back and change dwn-server to only return an error - //! if the server errored. - // was the error an error returned by dwn.processMessage or did the error happen at the server level? - if (lastDwnRpcResponse.error) { - const { error } = lastDwnRpcResponse; - if (error.data?.status) { - return { status: error.data!.status }; + if (!dwnReply) { + throw new Error(JSON.stringify(errorMessages)); + } + + return { + message : dwnRpcRequest.message, + messageCid : await Message.getCid(dwnRpcRequest.message), + reply : dwnReply, + }; + } + + async #getDwnMessage(author: string, messageType: string, messageCid: string): Promise { + const dwnSignatureInput = await this.#getAuthorSignatureInput(author); + const messagesGet = await MessagesGet.create({ + authorizationSignatureInput : dwnSignatureInput, + messageCids : [messageCid] + }); + + const result: MessagesGetReply = await this.dwn.processMessage(author, messagesGet.toJSON()); + const [ messageEntry ] = result.messages; + + if (!messageEntry) { + throw new Error('TODO: figure out error message'); + } + + let { message } = messageEntry; + if (!message) { + throw new Error('TODO: message not found'); + } + + let dwnMessage: DwnMessage = { message }; + + // if the message is a RecordsWrite, either data will be present, OR we have to fetch it using a RecordsRead + if (messageType === 'RecordsWrite') { + const { encodedData } = messageEntry; + message = message as RecordsWriteMessage; + + if (encodedData) { + const dataBytes = Encoder.base64UrlToBytes(encodedData); + dwnMessage.data = new Blob([dataBytes]); } else { - throw new Error(`(${error.code}) - ${error.message}`); + const recordsRead = await RecordsRead.create({ + authorizationSignatureInput : dwnSignatureInput, + recordId : message['recordId'] + }); + + const reply = await this.dwn.processMessage(author, recordsRead.toJSON()) as RecordsReadReply; + + if (reply.status.code >= 400) { + const { status: { code, detail } } = reply; + throw new Error(`(${code}) Failed to read data associated with record ${message['recordId']}. ${detail}}`); + } else { + const dataBytes = await DataStream.toBytes(reply.record.data); + dwnMessage.data = new Blob([dataBytes]); + } } } - // TODO: (Moe -> Frank): Chat with frank about what to return - return lastDwnRpcResponse.result; + return dwnMessage; } - // async getDwnMessage(request: SendDwnRequest): Promise { - // const dwnSignatureInput = await this.#getAuthorSignatureInput(request.author); - // const messagesGet = await MessagesGet.create({ - // authorizationSignatureInput : dwnSignatureInput, - // messageCids : [request.messageCid] - // }); - - // const result: MessagesGetReply = await this.dwn.processMessage(request.author, messagesGet.toJSON()); - // const [ messageEntry ] = result.messages; - - // if (!messageEntry) { - // throw new Error('TODO: figure out error message'); - // } - - // const { messageType } = request; - // let { message } = messageEntry; - - // if (!message) { - // throw new Error('TODO: message not found'); - // } - - // const dwnRpcRequest: Partial = { - // targetDid: request.author, - // message - // }; - // // if the message is a RecordsWrite, either data will be present, OR we have to fetch it using a RecordsRead - // if (messageType === 'RecordsWrite') { - // const { encodedData } = messageEntry; - // message = message as RecordsWriteMessage; - - // if (encodedData) { - // const dataBytes = Encoder.base64UrlToBytes(encodedData); - // dwnRpcRequest.data = new Blob([dataBytes]); - // } else { - // const recordsRead = await RecordsRead.create({ - // authorizationSignatureInput : dwnSignatureInput, - // recordId : message['recordId'] - // }); - - // // TODO: set reply type to RecordsReadReply once it is exported from dwn-sdk-js - // const reply = await this.dwn.processMessage(request.author, recordsRead.toJSON()); - // dwnRpcRequest.data = reply.data; - // } - // } - - // const { didDocument } = await this.didResolver.resolve(request.author); - // if (!didDocument) { - // throw new Error('TODO: figure out error message '); - // } - - // const [ service ] = didUtils.getServices(didDocument, { id: '#dwn' }); - - // if (!service) { - // throw new Error(`${request.author} has no dwn service endpoints`); - // } - - // const { serviceEndpoint } = service; - // if (!serviceEndpoint['nodes']) { - // throw new Error('malformed dwn service endpoint. expected nodes array'); - // } - - // const { nodes } = serviceEndpoint as DwnServiceEndpoint; - // let lastDwnRpcResponse: DwnRpcResponse; - - // // try sending to author's publicly addressable dwn's until first request succeeds. - // for (let node of nodes) { - // dwnRpcRequest.dwnUrl = node; - // // TODO: check for presence of error in dwnResponse.jsonRpcResponse. no point in blindly trying other nodes - // // if request is malformed. going to have to decide based on error code - - // // TODO: collect all responses - // const lastDwnRpcResponse = await this.dwnRpcClient.sendDwnRequest(dwnRpcRequest as DwnRpcRequest); - // if (lastDwnRpcResponse.error) { - // const { error } = lastDwnRpcResponse; - // if (sendRetryCodes.has(error.code)) { - // continue; - // } else { - // break; - // } - // } - // } - - // // if sending to the author's dwn(s) failed don't try the target's dwn - // if (lastDwnRpcResponse.error) { - // // TODO: figure out what SendDwnResponse looks like - // } - // } - async #constructDwnMessage(request: ProcessDwnRequest) { + // TODO: show henry the consequence of him choosing Readable + const dwnSignatureInput = await this.#getAuthorSignatureInput(request.author); + let readableStream: Readable; + // TODO: MOVE ALL THIS TO HTTP TRANSPORT LAND BECAUSE THATS WHY WE HAVE TO DO IT + // THANKS A LOT BROWSER NECKBEARDS if (request.messageType === 'RecordsWrite') { const messageOptions = request.messageOptions as RecordsWriteOptions; if (request.dataStream && !messageOptions.data) { const { dataStream } = request; + let isomorphicNodeReadable: Readable; if (dataStream instanceof Blob) { - messageOptions.dataSize = dataStream.size; + isomorphicNodeReadable = blobToIsomorphicNodeReadable(dataStream); + + readableStream = blobToIsomorphicNodeReadable(dataStream); + } else if (dataStream instanceof ReadableStream) { + const [ forCid, forProcessMessage ] = dataStream.tee(); - //! Note: this _won't_ work with nodejs because a blob's stream can only be consumed once - const isomorphicNodeReadable = blobToIsomorphicNodeReadable(dataStream); - messageOptions.dataCid = await Cid.computeDagPbCidFromStream(isomorphicNodeReadable); - } else if (dataStream instanceof Readable) { - // TODO: handle this? + isomorphicNodeReadable = webReadableToIsomorphicNodeReadable(forCid); + readableStream = webReadableToIsomorphicNodeReadable(forProcessMessage); } + + messageOptions.dataCid = await Cid.computeDagPbCidFromStream(isomorphicNodeReadable); + messageOptions.dataSize ??= isomorphicNodeReadable['bytesRead']; } } @@ -288,7 +267,7 @@ export class Web5UserAgent implements Web5Agent { const messageCreator = dwnMessageCreators[request.messageType]; const dwnMessage = await messageCreator.create(messageCreateInput as any); - return dwnMessage; + return { message: dwnMessage.toJSON(), dataStream: readableStream }; } /** diff --git a/packages/web5-user-agent/tests/common/web5-user-agent.spec.ts b/packages/web5-user-agent/tests/common/web5-user-agent.spec.ts index f7856aa76..37342d34a 100644 --- a/packages/web5-user-agent/tests/common/web5-user-agent.spec.ts +++ b/packages/web5-user-agent/tests/common/web5-user-agent.spec.ts @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import { Encoder, RecordsWriteMessage, RecordsRead } from '@tbd54566975/dwn-sdk-js'; import { TestAgent } from './utils/test-user-agent.js'; let testAgent: TestAgent; @@ -46,7 +47,8 @@ describe('Web5UserAgent', () => { type : 'dwn', id : 'dwn', serviceEndpoint : { - nodes: ['https://dwn.tbddev.org/dwn0'] + // nodes: ['https://dwn.tbddev.org/dwn0'] + nodes: ['http://localhost:3000'] } }] } @@ -64,7 +66,8 @@ describe('Web5UserAgent', () => { }); expect(response.reply).to.exist; - expect(response.error).to.not.exist; + expect(response.message).to.exist; + expect(response.messageCid).to.exist; expect(response.reply.status).to.exist; expect(response.reply.entries).to.exist; expect(response.reply.status.code).to.equal(200); @@ -77,7 +80,8 @@ describe('Web5UserAgent', () => { type : 'dwn', id : 'dwn', serviceEndpoint : { - nodes: ['https://dwn.tbddev.org/dwn0'] + // nodes: ['https://dwn.tbddev.org/dwn0'] + nodes: ['http://localhost:3000'] } }] } @@ -92,11 +96,9 @@ describe('Web5UserAgent', () => { } }); - // TODO: (Moe -> Frank): interesting that 202 is returned expect(response.reply).to.exist; - expect(response.error).to.not.exist; expect(response.reply.status).to.exist; - expect(response.reply.status.code).to.equal(202); + expect(response.reply.status.code).to.equal(404); }); it('returns something when an jwark is smorked', async () => { @@ -106,7 +108,8 @@ describe('Web5UserAgent', () => { type : 'dwn', id : 'dwn', serviceEndpoint : { - nodes: ['https://dwn.tbddev.org/dwn0'] + // nodes: ['https://dwn.tbddev.org/dwn0'] + nodes: ['http://localhost:3000'] } }] } @@ -127,5 +130,62 @@ describe('Web5UserAgent', () => { expect(e.message).to.include('/descriptor/filter'); } }); + + it('handles RecordsRead Messages', async () => { + const { did: aliceDid } = await testAgent.createProfile({ + profileDidOptions: { + services: [{ + type : 'dwn', + id : 'dwn', + serviceEndpoint : { + // nodes: ['https://dwn.tbddev.org/dwn0'] + nodes: ['http://localhost:3000'] + } + }] + } + }); + + const dataBytes = Encoder.stringToBytes('hi'); + + let response = await testAgent.agent.sendDwnRequest({ + author : aliceDid, + target : aliceDid, + messageType : 'RecordsWrite', + messageOptions : { + dataFormat : 'text/plain', + data : dataBytes + }, + dataStream: new Blob([dataBytes]) + }); + + const message = response.message as RecordsWriteMessage; + + response = await testAgent.agent.sendDwnRequest({ + author : aliceDid, + target : aliceDid, + messageType : 'RecordsRead', + messageOptions : { + recordId: message.recordId + } + }); + + expect(response.reply.status.code).to.equal(200); + expect(response.message).to.exist; + + const readMessage = response.message as RecordsRead['message']; + expect(readMessage.descriptor.method).to.equal('Read'); + expect(readMessage.descriptor.interface).to.equal('Records'); + + expect(response.reply['record']).to.exist; + + const record = response.reply['record'] as RecordsWriteMessage & { data: ReadableStream }; + expect(record.recordId).to.equal(message.recordId); + + expect(record.data).to.exist; + expect(record.data instanceof ReadableStream).to.be.true; + + const { value } = await record.data.getReader().read(); + expect(dataBytes).to.eql(value); + }); }); }); \ No newline at end of file diff --git a/packages/web5/package.json b/packages/web5/package.json index 529c32a95..0aaa98919 100644 --- a/packages/web5/package.json +++ b/packages/web5/package.json @@ -55,7 +55,7 @@ "@decentralized-identity/ion-tools": "1.0.7", "@tbd54566975/crypto": "0.1.0", "@tbd54566975/dids": "0.1.0", - "@tbd54566975/dwn-sdk-js": "0.0.31-unstable-2023-05-11-32b5f91", + "@tbd54566975/dwn-sdk-js": "0.0.32-unstable-2023-05-15-1350300", "@tbd54566975/web5-agent": "0.1.0", "@tbd54566975/web5-proxy-agent": "0.1.0", "@tbd54566975/web5-user-agent": "0.1.0", diff --git a/packages/web5/src/dwn-api.ts b/packages/web5/src/dwn-api.ts index 8494175ed..13e500028 100644 --- a/packages/web5/src/dwn-api.ts +++ b/packages/web5/src/dwn-api.ts @@ -10,12 +10,14 @@ import type { RecordsWriteDescriptor, RecordsWriteMessage, RecordsWriteOptions, + ProtocolsConfigureMessage } from '@tbd54566975/dwn-sdk-js'; -import { DwnInterfaceName, DwnMethodName, DataStream } from '@tbd54566975/dwn-sdk-js'; +import { DwnInterfaceName, DwnMethodName } from '@tbd54566975/dwn-sdk-js'; import { Record } from './record.js'; -import { dataToBytes, isDataSizeUnderCacheLimit, isEmptyObject } from './utils.js'; +import { Protocol } from './protocol.js'; +import { dataToBlob, isDataSizeUnderCacheLimit, isEmptyObject } from './utils.js'; // TODO: Export type ProtocolsConfigureDescriptor from dwn-sdk-js. export type ProtocolsConfigureDescriptor = { @@ -32,6 +34,7 @@ export type ProtocolsConfigureRequest = { export type ProtocolsConfigureResponse = { status: MessageReply['status']; + protocol?: Protocol; } export type ProtocolsQueryReplyEntry = { @@ -102,7 +105,7 @@ export type RecordsReadResponse = { export type RecordsWriteRequest = { data: unknown; - message?: Omit; + message?: Omit, 'authorizationSignatureInput'>; } export type RecordsWriteResponse = { @@ -132,9 +135,15 @@ export class DwnApi { messageType : DwnInterfaceName.Protocols + DwnMethodName.Configure }); - const { reply: { status }} = agentResponse; + const { message, messageCid, reply: { status }} = agentResponse; + const response: ProtocolsConfigureResponse = { status }; - return { status }; + if (status.code < 300) { + const metadata = { author: this.connectedDid, messageCid }; + response.protocol = new Protocol(this.web5Agent, message as ProtocolsConfigureMessage, metadata); + } + + return response; }, /** @@ -328,26 +337,16 @@ export class DwnApi { * from the DWN datastore. */ write: async (request: RecordsWriteRequest): Promise => { - const { data, message: requestMessage } = request; - const messageOptions: Partial = { - ...requestMessage + ...request.message }; - let dataStream; - if (data instanceof Blob || data instanceof ReadableStream) { - dataStream = data; - } else { - const { dataBytes, dataFormat } = dataToBytes(request.data, messageOptions.dataFormat); - messageOptions.data = dataBytes; - messageOptions.dataFormat = dataFormat; - - dataStream = DataStream.fromBytes(dataBytes); - } + const { dataBlob, dataFormat } = dataToBlob(request.data, messageOptions.dataFormat); + messageOptions.dataFormat = dataFormat; const agentResponse = await this.web5Agent.processDwnRequest({ author : this.connectedDid, - dataStream : dataStream as any, + dataStream : dataBlob, messageOptions, messageType : DwnInterfaceName.Records + DwnMethodName.Write, target : this.connectedDid @@ -358,13 +357,10 @@ export class DwnApi { let record: Record; if (200 <= status.code && status.code <= 299) { - // As a convenience, store a copy of relatively small data with the Record instance. - const encodedData = isDataSizeUnderCacheLimit(responseMessage.descriptor.dataSize) ? messageOptions.data : null; - const recordOptions = { - author : this.connectedDid, - encodedData, - target : this.connectedDid, + author : this.connectedDid, + encodedData : dataBlob, + target : this.connectedDid, ...responseMessage, }; diff --git a/packages/web5/src/protocol.ts b/packages/web5/src/protocol.ts new file mode 100644 index 000000000..699b7453f --- /dev/null +++ b/packages/web5/src/protocol.ts @@ -0,0 +1,36 @@ +import type { Web5Agent } from '@tbd54566975/web5-agent'; +import type { ProtocolsConfigure } from '@tbd54566975/dwn-sdk-js'; + +// TODO: export ProtocolsConfigureMessage from dwn-sdk-js +export type ProtocolsConfigureMessage = ProtocolsConfigure['message']; +type ProtocolMetadata = { + author: string; + messageCid: string; +}; + +export class Protocol { + #metadata: ProtocolMetadata; + #web5Agent: Web5Agent; + #protocolsConfigureMessage: ProtocolsConfigureMessage; + + constructor(web5Agent: Web5Agent, protocolsConfigureMessage: ProtocolsConfigureMessage, metadata: ProtocolMetadata) { + this.#metadata = metadata; + this.#web5Agent = web5Agent; + this.#protocolsConfigureMessage = protocolsConfigureMessage; + } + + toJSON() { + return this.#protocolsConfigureMessage; + } + + async send() { + const { reply } = await this.#web5Agent.sendDwnRequest({ + messageType : 'ProtocolsConfigure', + author : this.#metadata.author, + target : this.#metadata.author, + messageCid : this.#metadata.messageCid + }); + + return { status: reply.status }; + } +} \ No newline at end of file diff --git a/packages/web5/src/record.ts b/packages/web5/src/record.ts index 44badf6cd..7e9246a73 100644 --- a/packages/web5/src/record.ts +++ b/packages/web5/src/record.ts @@ -5,13 +5,13 @@ import type { RecordsReadReply, RecordsWriteDescriptor, RecordsWriteMessage, Rec import { ReadableWebToNodeStream } from 'readable-web-to-node-stream'; import { DataStream, DwnInterfaceName, DwnMethodName, Encoder } from '@tbd54566975/dwn-sdk-js'; -import { dataToBytes, isDataSizeUnderCacheLimit } from './utils.js'; +import { dataToBlob, isDataSizeUnderCacheLimit } from './utils.js'; import type { RecordsDeleteResponse } from './dwn-api.js'; export type RecordOptions = RecordsWriteMessage & { author: string; target: string; - encodedData?: string | Uint8Array; + encodedData?: string | Blob; data?: Readable | ReadableStream; }; @@ -42,7 +42,7 @@ export class Record implements RecordModel { #attestation?: RecordsWriteMessage['attestation']; #contextId?: string; #descriptor: RecordsWriteDescriptor; - #encodedData?: string | Uint8Array | null; + #encodedData?: string | Blob | null; #encryption?: RecordsWriteMessage['encryption']; #readableStream?: Readable | Promise; #recordId: string; @@ -84,8 +84,9 @@ export class Record implements RecordModel { this.#encryption = options.encryption; this.#recordId = options.recordId; - // If the record `dataSize is less than the DwnConstant.maxDataSizeAllowedToBeEncoded value, - // then an `encodedData` property will be present. + + // options.encodedData will either be a base64url encoded string (in the case of RecordsQuery) + // OR a Blob in the case of a RecordsWrite. this.#encodedData = options.encodedData ?? null; // If the record was created from a RecordsRead reply then it will have a `data` property. @@ -122,24 +123,30 @@ export class Record implements RecordModel { // type is Uint8Array bytes if the Record object was instantiated from a RecordsWrite response // type is Base64 URL encoded string if the Record object was instantiated from a RecordsQuery response // If it is a string, we need to Base64 URL decode to bytes - this.#encodedData = Encoder.base64UrlToBytes(this.#encodedData); + const dataBytes = Encoder.base64UrlToBytes(this.#encodedData); + this.#encodedData = new Blob([dataBytes]); } // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; // Capture the context of the `Record` instance. + const dataBlob = this.#encodedData as Blob; const dataObj = { + async blob(): Promise { + if (self.#encodedData) return self.#encodedData as Blob; + if (self.#readableStream) return new Blob([this.stream().then(DataStream.toBytes)]); + }, async json() { if (self.#encodedData) return this.text().then(JSON.parse); if (self.#readableStream) return this.text().then(JSON.parse); return null; }, async text() { - if (self.#encodedData) return Encoder.bytesToString(self.#encodedData as Uint8Array); + if (self.#encodedData) return dataBlob.text(); if (self.#readableStream) return this.stream().then(DataStream.toBytes).then(Encoder.bytesToString); return null; }, async stream() { - if (self.#encodedData) return DataStream.fromBytes(self.#encodedData as Uint8Array); + if (self.#encodedData) return new ReadableWebToNodeStream(dataBlob.stream()); if (self.#readableStream) return self.#readableStream; return null; }, @@ -183,16 +190,17 @@ export class Record implements RecordModel { async send(target: string): Promise { if (this.isDeleted) throw new Error(`Record with ID '${this.id}' was previously deleted.`); - const agentResponse = await this.#web5Agent.sendDwnRequest({ + const { reply: { status } } = await this.#web5Agent.sendDwnRequest({ + messageType : DwnInterfaceName.Records + DwnMethodName.Write, author : this.author, - // TODO: Frank -> Moe: The data in a Record instance is a node Readable. At what stage in processing should it be converted depending on whether its Web5ProxyAgent or Web5UserAgent. - // dataStream : await this.data.stream(), + dataStream : await this.data.blob(), target : target, messageOptions : this.toJSON(), - messageType : DwnInterfaceName.Records + DwnMethodName.Write, }); - console.log(agentResponse); + return { status }; + + // console.log(JSON.stringify(agentResponse, null, 2)); } /** @@ -254,20 +262,15 @@ export class Record implements RecordModel { // Begin assembling update message. let updateMessage = { ...this.#descriptor, ...options } as Partial; - let dataStream: _Readable.Readable; + let dataBlob: Blob; if (options.data !== undefined) { // If `data` is being updated then `dataCid` and `dataSize` must be undefined and the `data` property is passed as // a top-level property to `web5Agent.processDwnRequest()`. delete updateMessage.dataCid; delete updateMessage.dataSize; + delete updateMessage.data; - if (options.data instanceof Blob || options.data instanceof ReadableStream) { - //! TODO: get dataSize and dataCid of data - } else { - const { dataBytes } = dataToBytes(options.data, updateMessage.dataFormat); - updateMessage.data = dataBytes; - dataStream = DataStream.fromBytes(dataBytes); - } + ({ dataBlob } = dataToBlob(options.data, updateMessage.dataFormat)); } // Throw an error if an attempt is made to modify immutable properties. `data` has already been handled. @@ -297,7 +300,7 @@ export class Record implements RecordModel { const agentResponse = await this.#web5Agent.processDwnRequest({ author : this.author, - dataStream : dataStream as any, + dataStream : dataBlob, messageOptions, messageType : DwnInterfaceName.Records + DwnMethodName.Write, target : this.target, @@ -312,9 +315,8 @@ export class Record implements RecordModel { this.#descriptor[property] = responseMessage.descriptor[property]; }); // Only cache data if `dataSize` is less than DWN 'max data size allowed to be encoded'. - if (updateMessage.data !== undefined) { - this.#readableStream = isDataSizeUnderCacheLimit(responseMessage.descriptor.dataSize) ? DataStream.fromBytes(updateMessage.data) : null; - this.#encodedData = null; // Clear `encodedData` in case it was previously set. + if (options.data !== undefined) { + this.#encodedData = dataBlob; // Clear `encodedData` in case it was previously set. } } diff --git a/packages/web5/src/utils.ts b/packages/web5/src/utils.ts index 3491fa2a7..438c70451 100644 --- a/packages/web5/src/utils.ts +++ b/packages/web5/src/utils.ts @@ -37,23 +37,27 @@ export function isDataSizeUnderCacheLimit(dataSize: number): boolean { /** * Set/detect the media type and return the data as bytes. */ -export const dataToBytes = (data: any, dataFormat?: string) => { - let dataBytes = data; +export const dataToBlob = (data: any, dataFormat?: string) => { + let dataBlob: Blob; // Check for Object or String, and if neither, assume bytes. const detectedType = toType(data); - if ((dataFormat === 'text/plain') || (detectedType === 'string')) { - dataFormat = 'text/plain'; - dataBytes = Encoder.stringToBytes(data); - } - else if ((dataFormat === 'application/json') || (detectedType === 'object')) { - dataFormat = 'application/json'; - dataBytes = Encoder.objectToBytes(data); - } else if (!dataFormat) { - dataFormat = 'application/octet-stream'; + if (dataFormat === 'text/plain' || detectedType === 'string') { + dataBlob = new Blob([data], { type: 'text/plain' }); + } else if (dataFormat === 'application/json' || detectedType === 'object') { + const dataBytes = Encoder.objectToBytes(data); + dataBlob = new Blob([dataBytes], { type: 'application/json' }); + } else if (data instanceof Uint8Array || data instanceof ArrayBuffer) { + dataBlob = new Blob([data], { type: 'application/octet-stream' }); + } else if (data instanceof Blob) { + dataBlob = data; + } else { + throw new Error('data type not supported.'); } - return { dataBytes, dataFormat }; + dataFormat = dataFormat || dataBlob.type || 'application/octet-stream'; + + return { dataBlob, dataFormat }; }; export function isEmptyObject(obj) { diff --git a/packages/web5/tests/fixtures/protocol-definitions/email.json b/packages/web5/tests/fixtures/protocol-definitions/email.json new file mode 100644 index 000000000..67e56f3c6 --- /dev/null +++ b/packages/web5/tests/fixtures/protocol-definitions/email.json @@ -0,0 +1,49 @@ +{ + "protocol": "http://email-protocol.xyz", + "types": { + "email": { + "schema": "email", + "dataFormats": [ + "text/plain" + ] + } + }, + "structure": { + "email": { + "$actions": [ + { + "who": "anyone", + "can": "write" + }, + { + "who": "author", + "of": "email", + "can": "read" + }, + { + "who": "recipient", + "of": "email", + "can": "read" + } + ], + "email": { + "$actions": [ + { + "who": "anyone", + "can": "write" + }, + { + "who": "author", + "of": "email/email", + "can": "read" + }, + { + "who": "recipient", + "of": "email/email", + "can": "read" + } + ] + } + } + } +} \ No newline at end of file diff --git a/packages/web5/tests/fixtures/test-profiles.ts b/packages/web5/tests/fixtures/test-profiles.ts index 25fa50707..fa5a820e9 100644 --- a/packages/web5/tests/fixtures/test-profiles.ts +++ b/packages/web5/tests/fixtures/test-profiles.ts @@ -67,7 +67,8 @@ export const ionCreateOptions = { id : 'dwn', type : 'DecentralizedWebNode', serviceEndpoint : { - nodes : ['https://dwn.tbddev.org/dwn0'], + nodes : ['http://localhost:3000'], + // nodes : ['https://dwn.tbddev.org/dwn0'], messageAttestationKeys : [`#${keyIds.did.service.dwn.attestation}`], messageAuthorizationKeys : [`#${keyIds.did.service.dwn.authorization}`], recordEncryptionKeys : [`#${keyIds.did.service.dwn.encryption}`] @@ -89,7 +90,8 @@ export const ionCreateOptions = { id : 'dwn', type : 'DecentralizedWebNode', serviceEndpoint : { - nodes : ['https://dwn.tbddev.org/dwn0'], + nodes : ['http://localhost:3000'], + // nodes : ['https://dwn.tbddev.org/dwn0'], messageAuthorizationKeys : [`#${keyIds.did.service.dwn.authorization}`], } }] diff --git a/packages/web5/tests/record.spec.ts b/packages/web5/tests/record.spec.ts index 742e941cf..2fed2a0b9 100644 --- a/packages/web5/tests/record.spec.ts +++ b/packages/web5/tests/record.spec.ts @@ -3,13 +3,16 @@ import type { PrivateJwk as DwnPrivateKeyJwk, PublicJwk as DwnPublicKeyJwk, Rec import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; +import emailProtocolDefinition from './fixtures/protocol-definitions/email.json' assert { type: 'json' }; + import { utils as didUtils } from '@tbd54566975/dids'; import { DwnInterfaceName, DwnMethodName, KeyDerivationScheme, RecordsWrite } from '@tbd54566975/dwn-sdk-js'; +import * as testProfile from './fixtures/test-profiles.js'; + import { Record } from '../src/record.js'; import { DwnApi } from '../src/dwn-api.js'; -import { dataToBytes } from '../src/utils.js'; -import * as testProfile from './fixtures/test-profiles.js'; +import { dataToBlob } from '../src/utils.js'; import { TestDataGenerator } from './test-utils/test-data-generator.js'; import { TestAgent, TestProfileOptions } from './test-utils/test-user-agent.js'; @@ -20,27 +23,28 @@ type RecordsWriteTest = RecordsWrite & RecordsWriteMessage; let testAgent: TestAgent; let testProfileOptions: TestProfileOptions; -let did: string; +let aliceDid: string; let dwn: DwnApi; let didAllKeys: string; let dataText: string; -let dataBytes: Uint8Array; +let dataBlob: Blob; let dataFormat: string; describe('Record', () => { before(async () => { testAgent = await TestAgent.create(); dataText = TestDataGenerator.randomString(100); - ({ dataBytes, dataFormat } = dataToBytes(dataText)); + ({ dataBlob, dataFormat } = dataToBlob(dataText)); }); beforeEach(async () => { await testAgent.clearStorage(); - ({ did } = await testAgent.createProfile()); - dwn = new DwnApi(testAgent.agent, did); testProfileOptions = await testProfile.ion.with.dwn.service.and.authorization.encryption.attestation.keys(); ({ did: didAllKeys } = await testAgent.createProfile(testProfileOptions)); + + dwn = new DwnApi(testAgent.agent, didAllKeys); + }); after(async () => { @@ -117,7 +121,7 @@ describe('Record', () => { protocol, protocolPath, schema, - data : dataBytes, + data : new Uint8Array(await dataBlob.arrayBuffer()), dataFormat, authorizationSignatureInput : authorization, }) as RecordsWriteTest; @@ -129,7 +133,7 @@ describe('Record', () => { recipient, schema, parentId : parentRecorsWrite.recordId, - data : dataBytes, + data : new Uint8Array(await dataBlob.arrayBuffer()), published, dataFormat, attestationSignatureInputs : attestation, @@ -140,7 +144,7 @@ describe('Record', () => { // Create record using test RecordsWriteMessage. const record = new Record(testAgent.agent, { ...recordsWrite.message, - encodedData: dataBytes, + encodedData: dataBlob, target, author, }); @@ -273,7 +277,52 @@ describe('Record', () => { }); describe('send()', () => { - xit('tests needed'); + it('works', async () => { + // install a protocol for alice + let { protocol: aliceProtocol, status: aliceStatus } = await dwn.protocols.configure({ + message: { + definition: emailProtocolDefinition + } + }); + + expect(aliceStatus.code).to.equal(202); + expect(aliceProtocol).to.exist; + + const { status: alicePushStatus } = await aliceProtocol!.send(); + expect(alicePushStatus.code).to.equal(202); + + // install a protocol for bob + testProfileOptions = await testProfile.ion.with.dwn.service.and.authorization.encryption.attestation.keys(); + const { did: bobDid } = await testAgent.createProfile(testProfileOptions); + const bobDwn = new DwnApi(testAgent.agent, bobDid); + + const { protocol: bobProtocol, status: bobStatus } = await bobDwn.protocols.configure({ + message: { + definition: emailProtocolDefinition + } + }); + + expect(bobStatus.code).to.equal(202); + expect(bobProtocol).to.exist; + + const { status: bobPushStatus } = await bobProtocol!.send(); + expect(bobPushStatus.code).to.equal(202); + + // alice writes a message to her own dwn + const { status: aliceEmailStatus, record: aliceEmailRecord } = await dwn.records.write({ + data : 'Herro!', + message : { + protocol : emailProtocolDefinition.protocol, + protocolPath : 'email', + schema : 'email', + } + }); + + expect(aliceEmailStatus.code).to.equal(202); + + const { status } = await aliceEmailRecord!.send(bobDid); + expect(status.code).to.equal(202); + }); }); describe('toJSON()', () => { @@ -346,7 +395,7 @@ describe('Record', () => { protocol, protocolPath, schema, - data : dataBytes, + data : new Uint8Array(await dataBlob.arrayBuffer()), dataFormat, authorizationSignatureInput : authorization, }) as RecordsWriteTest; @@ -358,7 +407,7 @@ describe('Record', () => { recipient, schema, parentId : parentRecorsWrite.recordId, - data : dataBytes, + data : new Uint8Array(await dataBlob.arrayBuffer()), published, dataFormat, attestationSignatureInputs : attestation, @@ -369,7 +418,7 @@ describe('Record', () => { // Create record using test RecordsWriteMessage. const record = new Record(testAgent.agent, { ...recordsWrite.message, - encodedData: dataBytes, + encodedData: dataBlob, target, author, }); diff --git a/packages/web5/tests/web5-dwn.spec.ts b/packages/web5/tests/web5-dwn.spec.ts index 18b395fe8..54fd36597 100644 --- a/packages/web5/tests/web5-dwn.spec.ts +++ b/packages/web5/tests/web5-dwn.spec.ts @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { DwnApi } from '../src/dwn-api.js'; import * as testProfile from './fixtures/test-profiles.js'; import { TestAgent, TestProfileOptions } from './test-utils/test-user-agent.js'; -import messageProtocolDefinition from './fixtures/protocol-definitions/message.json' assert { type: 'json' }; +import emailProtocolDefinition from './fixtures/protocol-definitions/email.json' assert { type: 'json' }; let didOnlyAuthz: string; let dwn: DwnApi; @@ -32,13 +32,9 @@ describe('web5.dwn', () => { describe('configure', () => { describe('agent', () => { it('writes a protocol definition', async () => { - const protocolUri = 'https://protocols.xyz/message/protocol'; - const protocolDefinition = messageProtocolDefinition; - const response = await dwn.protocols.configure({ message: { - protocol : protocolUri, - definition : protocolDefinition + definition: emailProtocolDefinition } }); @@ -57,12 +53,9 @@ describe('web5.dwn', () => { it('should return protocols matching the query', async () => { let response; // Write a protocols configure to the connected agent's DWN. - const protocolUri = 'https://protocols.xyz/message/protocol'; - const protocolDefinition = messageProtocolDefinition; response = await dwn.protocols.configure({ message: { - protocol : protocolUri, - definition : protocolDefinition + definition: emailProtocolDefinition } }); expect(response.status.code).to.equal(202); @@ -72,17 +65,17 @@ describe('web5.dwn', () => { response = await dwn.protocols.query({ message: { filter: { - protocol: protocolUri + protocol: emailProtocolDefinition.protocol } } }); expect(response.status.code).to.equal(200); expect(response.protocols.length).to.equal(1); - expect(response.protocols[0].descriptor).to.have.property('protocol'); expect(response.protocols[0].descriptor).to.have.property('definition'); - expect(response.protocols[0].descriptor.protocol).to.equal(protocolUri); expect(response.protocols[0].descriptor.definition).to.have.property('types'); + expect(response.protocols[0].descriptor.definition).to.have.property('protocol'); + expect(response.protocols[0].descriptor.definition.protocol).to.equal(emailProtocolDefinition.protocol); expect(response.protocols[0].descriptor.definition).to.have.property('structure'); }); }); @@ -291,41 +284,13 @@ describe('web5.dwn', () => { expect(deleteResult.status.code).to.equal(202); }); - it('returns a 202 no matter what?', async () => { - const writeResult = await dwn.records.write({ - data : 'Hello, world!', - message : { - schema : 'foo/bar', - dataFormat : 'text/plain' - } - }); - - expect(writeResult.status.code).to.equal(202); - expect(writeResult.record).to.not.be.undefined; - - let deleteResult = await dwn.records.delete({ - message: { - recordId: writeResult.record!.id - } - }); - - // TODO: (Moe -> Frank): this returns a 202. interesting - deleteResult = await dwn.records.delete({ - message: { - recordId: writeResult.record!.id - } - }); - - expect(deleteResult.status.code).to.equal(202); - }); - - it('returns a 202 when the specified record does not exist', async () => { + it('returns a 404 when the specified record does not exist', async () => { let deleteResult = await dwn.records.delete({ message: { recordId: 'abcd1234' } }); - expect(deleteResult.status.code).to.equal(202); + expect(deleteResult.status.code).to.equal(404); }); });