From 14dd42d6a08ece197f8945e7b6f00ed1efe84343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Rib=C3=B3=20Labrador?= Date: Tue, 27 Feb 2024 12:23:01 +0100 Subject: [PATCH] fix: add reference app + mediator live mode (#177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Francisco Javier Ribó Labrador --- .github/workflows/ci.yml | 1 + README.md | 1 + demos/next/package-lock.json | 348 ++++++--- demos/next/package.json | 14 +- demos/next/src/actions/index.ts | 258 +++++++ demos/next/src/actions/types.ts | 13 + demos/next/src/app/App.css | 4 - demos/next/src/app/Box.tsx | 8 +- demos/next/src/app/globals.css | 9 +- demos/next/src/app/index.css | 134 +++- demos/next/src/app/layout.tsx | 8 +- demos/next/src/app/state.ts | 6 - demos/next/src/components/AgentRequire.tsx | 41 ++ demos/next/src/components/DBConnect.tsx | 42 ++ demos/next/src/components/Dids.tsx | 127 ++++ .../next/src/components/FooterNavigation.tsx | 40 + demos/next/src/components/Keypair.tsx | 140 ++++ demos/next/src/components/Message.tsx | 449 +++++++++++ demos/next/src/components/Mnemonics.tsx | 47 ++ demos/next/src/components/OOB.tsx | 63 ++ demos/next/src/pages/_app.tsx | 12 + demos/next/src/pages/connections.tsx | 50 ++ demos/next/src/pages/credentials.tsx | 92 +++ demos/next/src/pages/debug.tsx | 50 ++ demos/next/src/pages/index.tsx | 694 ++---------------- demos/next/src/pages/messages.tsx | 43 ++ demos/next/src/reducers/app.ts | 266 +++++++ demos/next/src/reducers/index.ts | 9 + demos/next/src/reducers/store.ts | 41 ++ demos/next/src/utils/types.ts | 1 + demos/next/tailwind.config.ts | 52 +- demos/next/tsconfig.json | 6 +- package-lock.json | 96 ++- package.json | 4 +- src/mercury/Mercury.ts | 16 +- src/mercury/didcomm/Wrapper.ts | 3 + src/prism-agent/Agent.ts | 7 +- .../connectionsManager/ConnectionsManager.ts | 50 +- src/prism-agent/helpers/Task.ts | 16 +- .../mediator/BasicMediatorHandler.ts | 61 +- src/prism-agent/protocols/ProtocolTypes.ts | 1 + src/prism-agent/types/index.ts | 6 + 42 files changed, 2562 insertions(+), 767 deletions(-) create mode 100644 demos/next/src/actions/index.ts create mode 100644 demos/next/src/actions/types.ts delete mode 100644 demos/next/src/app/App.css delete mode 100644 demos/next/src/app/state.ts create mode 100644 demos/next/src/components/AgentRequire.tsx create mode 100644 demos/next/src/components/DBConnect.tsx create mode 100644 demos/next/src/components/Dids.tsx create mode 100644 demos/next/src/components/FooterNavigation.tsx create mode 100644 demos/next/src/components/Keypair.tsx create mode 100644 demos/next/src/components/Message.tsx create mode 100644 demos/next/src/components/Mnemonics.tsx create mode 100644 demos/next/src/components/OOB.tsx create mode 100644 demos/next/src/pages/_app.tsx create mode 100644 demos/next/src/pages/connections.tsx create mode 100644 demos/next/src/pages/credentials.tsx create mode 100644 demos/next/src/pages/debug.tsx create mode 100644 demos/next/src/pages/messages.tsx create mode 100644 demos/next/src/reducers/app.ts create mode 100644 demos/next/src/reducers/index.ts create mode 100644 demos/next/src/reducers/store.ts create mode 100644 demos/next/src/utils/types.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d193f8990..af3a9d739 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,7 @@ jobs: audit_level: moderate create_issues: false github_token: ${{ secrets.GITHUB_TOKEN }} + production_flag: true - name: Jest Coverage Comment uses: MishaKav/jest-coverage-comment@v1.0.23 diff --git a/README.md b/README.md index 8c2e748aa..7cff58186 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Browser NextJS ```bash cd demos/next npm i +npm run build # becuase Error: ENOENT: no such file or directory, open '/.../atala-prism-wallet-sdk-ts/demos/next/.next/BUILD_ID'] npm run start ``` diff --git a/demos/next/package-lock.json b/demos/next/package-lock.json index 02d353b48..d9045e401 100644 --- a/demos/next/package-lock.json +++ b/demos/next/package-lock.json @@ -8,16 +8,22 @@ "name": "atala-prism-nextjs", "version": "0.1.0", "dependencies": { - "@atala/prism-wallet-sdk": "../..", - "@pluto-encrypted/database": "^1.2.14", - "@pluto-encrypted/inmemory": "^1.3.11", + "@atala/prism-wallet-sdk": "../../", + "@noble/hashes": "^1.3.3", + "@pluto-encrypted/database": "^1.15.5", + "@pluto-encrypted/indexdb": "^1.12.2", + "@pluto-encrypted/schemas": "^1.3.5", + "@reduxjs/toolkit": "^1.9.5", "fs": "^0.0.1-security", "jose": "^5.2.0", "jotai": "^2.6.1", "next": "14.0.4", "path": "^0.12.7", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-redux": "^7.2.6", + "redux": "^4.1.2", + "redux-thunk": "^2.4.0" }, "devDependencies": { "@types/node": "^20", @@ -35,7 +41,7 @@ "version": "3.1.0", "license": "Apache-2.0", "dependencies": { - "@atala/apollo": "^1.2.7", + "@atala/apollo": "^1.2.10", "@scure/bip32": "^1.3.0", "@scure/bip39": "^1.1.1", "@stablelib/base64": "^1.0.1", @@ -56,6 +62,7 @@ "jose": "^4.12.2", "jsonwebtoken": "^9.0.0", "multiformats": "^9.9.0", + "socket.io-client": "^4.7.4", "text-encoding": "^0.7.0", "util": "^0.12.5", "uuid": "^9.0.0" @@ -69,6 +76,7 @@ "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@babel/traverse": "^7.23.2", + "@droppedcode/typedoc-plugin-relative-includes": "^1.0.5", "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.2.1", @@ -126,11 +134,10 @@ "semantic-release-slack-bot": "^4.0.2", "sinon": "^15.0.1", "sinon-chai": "^3.7.0", - "typedoc": "^0.24.8", - "typedoc-plugin-markdown": "3.15.3", - "typedoc-plugin-rename-defaults": "^0.6.5", - "typedoc-plugin-superstruct": "^1.0.0", - "typedoc-theme-hierarchy": "^4.0.0", + "typedoc": "^0.25.6", + "typedoc-plugin-external-module-map": "^2.0.1", + "typedoc-plugin-markdown": "^3.17.1", + "typedoc-plugin-rename-defaults": "^0.7.0", "typescript": "^4.9.5" }, "peerDependenciesMeta": { @@ -161,9 +168,9 @@ } }, "node_modules/@atala/apollo": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@atala/apollo/-/apollo-1.2.7.tgz", - "integrity": "sha512-xHSj1RbKfkfM1gIo2V8u9/RItTZaE0X8wuY6zJLPSu9KtUCpnVecuV0A48giI6/7HTm3JJFe1ad6Hs2X0T1JhQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@atala/apollo/-/apollo-1.2.10.tgz", + "integrity": "sha512-0uoA76e3eE0gl9h7/77GtgoYsX2OvM+rWdDkA5mOR2WB6XU4lGrVdXv954WNjpNQaNcMwkeh2INje51d7RuAIw==", "dependencies": { "@noble/curves": "1.2.0", "@noble/hashes": "1.3.1", @@ -217,7 +224,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.7.tgz", "integrity": "sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -817,9 +823,9 @@ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/@grpc/grpc-js/node_modules/protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -1054,9 +1060,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", - "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", + "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -1286,31 +1292,33 @@ } }, "node_modules/@pluto-encrypted/database": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/database/-/database-1.2.14.tgz", - "integrity": "sha512-pNhjvCOArX7FHLLxh7POc6kYvRj7ridz/KuY9yTWjGGJm2kWfp2JU4Z4tvF6FzjZv8lvKP1jBnTinowwONCYfQ==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/database/-/database-1.15.5.tgz", + "integrity": "sha512-p2CXc0lD5DyRcA4WWrqxySPouEKMUvJhoBu81iVvNBSaIqS9zVJveOmJKdeTA2M6KKD1/I0478ntk/DhKDfshg==", "dependencies": { - "@atala/prism-wallet-sdk": "^3.2.0", - "@pluto-encrypted/encryption": "^1.2.3", + "@atala/prism-wallet-sdk": "^4.0.2", + "@pluto-encrypted/encryption": "1.11.0", + "@pluto-encrypted/schemas": "^1.3.5", + "@pluto-encrypted/shared": "1.11.3", "rxdb": "^14.17.0", "rxjs": "7.8.1", "uuid": "^9.0.1" }, "optionalDependencies": { - "@pluto-encrypted/indexdb": "1.3.11", - "@pluto-encrypted/inmemory": "1.3.11", - "@pluto-encrypted/leveldb": "1.3.11" + "@pluto-encrypted/indexdb": "1.12.2", + "@pluto-encrypted/inmemory": "1.12.2", + "@pluto-encrypted/leveldb": "1.12.2" }, "peerDependencies": { - "@atala/prism-wallet-sdk": "^3.2.0" + "@atala/prism-wallet-sdk": "^4.0.2" } }, "node_modules/@pluto-encrypted/database/node_modules/@atala/prism-wallet-sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@atala/prism-wallet-sdk/-/prism-wallet-sdk-3.2.0.tgz", - "integrity": "sha512-g3G5LJfvEYVQIavnRL9v7VazEw7hR6wimfAymcnx013krsf4xrnPGMQXoBHSZGJp3ch/upD02zGaS3KCWqS1Yg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@atala/prism-wallet-sdk/-/prism-wallet-sdk-4.0.2.tgz", + "integrity": "sha512-dAQTvFeg8oZsO022ICOWZ/8mfowwXwz26J70VQrFT5drqhIvTER4d7T2CLEgBytchHIk6ueowCGcBlL+JIe9tA==", "dependencies": { - "@atala/apollo": "^1.1.1", + "@atala/apollo": "^1.2.10", "@scure/bip32": "^1.3.0", "@scure/bip39": "^1.1.1", "@stablelib/base64": "^1.0.1", @@ -1362,9 +1370,9 @@ } }, "node_modules/@pluto-encrypted/encryption": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/encryption/-/encryption-1.2.8.tgz", - "integrity": "sha512-J065/N7qFeMOOGtEhzngGMaeITgnfv/rkfiJ3E8laa6Pb2rxKuPC4O0jMCP9Q5246glNqo+3KJPd9WqGnfJwDg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/encryption/-/encryption-1.11.0.tgz", + "integrity": "sha512-f3dyJGod0CMqBZP/UCeP8hZBH278BP1Wquq/aq+16/z5t1UZMQq+wTG3JnMx2Yn+ivx70WjTaPlmKNrw4mjUqw==", "dependencies": { "@noble/ciphers": "^0.4.1", "@noble/curves": "^1.3.0", @@ -1376,38 +1384,38 @@ } }, "node_modules/@pluto-encrypted/indexdb": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/indexdb/-/indexdb-1.3.11.tgz", - "integrity": "sha512-cRy16yPH4cNd6JP7i9MCjyiwjnWVvBgXyw8k/T0mLyBQZzIlwyqSzHa6bpSOYBocs8eaiv1E4qui26p4JHQkqA==", - "optional": true, + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/indexdb/-/indexdb-1.12.2.tgz", + "integrity": "sha512-Qt3ehyCWqrCFUyh8Q4IE5He6Qz89roC7FXlGk9az0p6Sl1oHwDMgZDq4JgYIU4gKVtapWsUiidfAt53PtJlCFg==", "dependencies": { - "@pluto-encrypted/encryption": "1.2.8", - "@pluto-encrypted/shared": "1.2.8", + "@pluto-encrypted/encryption": "1.11.0", + "@pluto-encrypted/shared": "1.11.3", "array-push-at-sort-position": "^4.0.1", "rxdb": "^14.17.0", "uuid": "^9.0.1" } }, "node_modules/@pluto-encrypted/inmemory": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/inmemory/-/inmemory-1.3.11.tgz", - "integrity": "sha512-dmj5CM7aQuFl/uyzKlmP6DEk8n//HckPqDaRJSSx1cZR3kcMRMsPceudpjbHl+yHlb9SkugOqZ0nQyAj5tWHHQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/inmemory/-/inmemory-1.12.2.tgz", + "integrity": "sha512-N5tZahPgrKM7HNSSUtHC6sRDnn2ytJw8sbYY/qnfOOjlQnZJhDfVUm8AXWi9wlRddMhvpPRadHhl2Qd1BY3L1g==", + "optional": true, "dependencies": { - "@pluto-encrypted/encryption": "1.2.8", - "@pluto-encrypted/shared": "1.2.8", + "@pluto-encrypted/encryption": "1.11.0", + "@pluto-encrypted/shared": "1.11.3", "array-push-at-sort-position": "^4.0.1", "rxdb": "^14.17.0", "uuid": "^9.0.1" } }, "node_modules/@pluto-encrypted/leveldb": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/leveldb/-/leveldb-1.3.11.tgz", - "integrity": "sha512-P4a5cYRPhDkPebnHOOEeDu+JM/x3CrjqvhcllNMdpLquA7dZjeTqwQ7JdC8EDxTrRqAaH07zdQX+hyzVwKLz4g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/leveldb/-/leveldb-1.12.2.tgz", + "integrity": "sha512-ibOn1l0mCotekWhsJ8vJ4zDNRrIsa5WOmN4oXIx1TYNwwLL8MQmvQKwN/ydMV4hpWhkJsafej5RBhFSosxOxKQ==", "optional": true, "dependencies": { - "@pluto-encrypted/encryption": "^1.2.3", - "@pluto-encrypted/shared": "^1.2.3", + "@pluto-encrypted/encryption": "1.11.0", + "@pluto-encrypted/shared": "1.11.3", "array-push-at-sort-position": "^4.0.1", "level": "^6.0.1", "module-error": "^1.0.2", @@ -1417,11 +1425,84 @@ "uuid": "^9.0.1" } }, + "node_modules/@pluto-encrypted/schemas": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/schemas/-/schemas-1.3.5.tgz", + "integrity": "sha512-ePr6AKFIuCv1KjBWCJEd2UeQVZdXR1jL9iYL38w5z5OezFFWEV9i4Be8QHmxa6UuTGBLKrAtUDdlS8PHL+aeMA==", + "dependencies": { + "@atala/prism-wallet-sdk": "^4.0.2", + "@pluto-encrypted/encryption": "1.11.0", + "@pluto-encrypted/shared": "1.11.3", + "rxdb": "^14.17.0", + "rxjs": "7.8.1", + "uuid": "^9.0.1" + }, + "peerDependencies": { + "@atala/prism-wallet-sdk": "^4.0.2" + } + }, + "node_modules/@pluto-encrypted/schemas/node_modules/@atala/prism-wallet-sdk": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@atala/prism-wallet-sdk/-/prism-wallet-sdk-4.0.2.tgz", + "integrity": "sha512-dAQTvFeg8oZsO022ICOWZ/8mfowwXwz26J70VQrFT5drqhIvTER4d7T2CLEgBytchHIk6ueowCGcBlL+JIe9tA==", + "dependencies": { + "@atala/apollo": "^1.2.10", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.1.1", + "@stablelib/base64": "^1.0.1", + "@stablelib/sha256": "^1.0.1", + "@stablelib/uuid": "^1.0.2", + "@stablelib/wipe": "^1.0.1", + "@stablelib/x25519": "^1.0.3", + "antlr4ts": "^0.5.0-alpha.4", + "assert": "^2.0.0", + "axios": "^1.6.1", + "bn.js": "^5.2.1", + "buffer": "^6.0.3", + "did-jwt": "^6.11.5", + "did-resolver": "^4.1.0", + "elliptic": "^6.5.4", + "google-protobuf": "^3.21.2", + "hash.js": "1.1.7", + "jose": "^4.12.2", + "jsonwebtoken": "^9.0.0", + "multiformats": "^9.9.0", + "text-encoding": "^0.7.0", + "util": "^0.12.5", + "uuid": "^9.0.0" + }, + "peerDependenciesMeta": { + "react-native-sqlite-storage": { + "optional": true + } + } + }, + "node_modules/@pluto-encrypted/schemas/node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@pluto-encrypted/schemas/node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/@pluto-encrypted/shared": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@pluto-encrypted/shared/-/shared-1.2.8.tgz", - "integrity": "sha512-NzgMsN/0EtJVginPrqevZH3DEoXENaFeSJBScIJLH39Kw5PA2yxVsWtADybnur/mKjX06crYrtMWboWEIHu5gg==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@pluto-encrypted/shared/-/shared-1.11.3.tgz", + "integrity": "sha512-/Ud10UeA7l+E9dM5rrfo5ED0U7kKwVgatsI+vL1EGs8/4W7OZXECP3DsDl/JnjH8GC/gH3ddql8U9PviWFi2ig==", "dependencies": { + "@pluto-encrypted/encryption": "1.11.0", "rxdb": "^14.17.0", "uuid": "^9.0.1" } @@ -1480,6 +1561,29 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz", @@ -1763,9 +1867,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -1773,6 +1877,15 @@ "@types/send": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -1815,8 +1928,7 @@ "node_modules/@types/prop-types": { "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "devOptional": true + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/qs": { "version": "6.9.11", @@ -1832,7 +1944,6 @@ "version": "18.2.46", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.46.tgz", "integrity": "sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==", - "devOptional": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1848,11 +1959,21 @@ "@types/react": "*" } }, + "node_modules/@types/react-redux": { + "version": "7.1.33", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.33.tgz", + "integrity": "sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "devOptional": true + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, "node_modules/@types/send": { "version": "0.17.4", @@ -2422,11 +2543,11 @@ } }, "node_modules/axios": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", - "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -2574,9 +2695,9 @@ } }, "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", + "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", "engines": { "node": ">=16.20.1" } @@ -2837,8 +2958,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/custom-idle-queue": { "version": "3.0.1", @@ -3133,9 +3253,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", - "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "engines": { "node": ">=10.0.0" } @@ -3893,9 +4013,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -4335,6 +4455,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", @@ -4379,6 +4507,15 @@ "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", "optional": true }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -5772,7 +5909,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6303,7 +6439,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -6459,8 +6594,36 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/read-cache": { "version": "1.0.0", @@ -6501,6 +6664,22 @@ "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz", "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==" }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "peerDependencies": { + "redux": "^4" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -6558,6 +6737,11 @@ "node": ">=0.10.0" } }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", diff --git a/demos/next/package.json b/demos/next/package.json index f1a8f4a76..7e4f66ac5 100644 --- a/demos/next/package.json +++ b/demos/next/package.json @@ -9,16 +9,22 @@ "lint": "next lint" }, "dependencies": { - "@atala/prism-wallet-sdk": "../..", - "@pluto-encrypted/database": "^1.2.14", - "@pluto-encrypted/inmemory": "^1.3.11", + "@atala/prism-wallet-sdk": "../../", + "@pluto-encrypted/database": "^1.15.5", + "@pluto-encrypted/indexdb": "^1.12.2", + "@pluto-encrypted/schemas": "^1.3.5", "fs": "^0.0.1-security", + "@noble/hashes": "^1.3.3", "jose": "^5.2.0", "jotai": "^2.6.1", "next": "14.0.4", "path": "^0.12.7", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-redux": "^7.2.6", + "redux": "^4.1.2", + "redux-thunk": "^2.4.0", + "@reduxjs/toolkit": "^1.9.5" }, "devDependencies": { "@types/node": "^20", diff --git a/demos/next/src/actions/index.ts b/demos/next/src/actions/index.ts new file mode 100644 index 000000000..725e4ca55 --- /dev/null +++ b/demos/next/src/actions/index.ts @@ -0,0 +1,258 @@ +import { addRxPlugin } from "rxdb"; +import { RxDBDevModePlugin } from "rxdb/plugins/dev-mode"; + +addRxPlugin(RxDBDevModePlugin); + +import { AnyAction, ThunkDispatch, createAsyncThunk } from "@reduxjs/toolkit"; +import SDK from "@atala/prism-wallet-sdk"; +import { Database } from "@pluto-encrypted/database"; +import { sha512 } from '@noble/hashes/sha512' +import { RootState, reduxActions } from "@/reducers/app"; +import { DBNAME } from "@/utils/types"; +import IndexDB from '@pluto-encrypted/indexdb' +import { + getDefaultCollections, + DIDCollection, + DIDPairCollection, + MediatorCollection, + PrivateKeyColletion, + CredentialCollection, + CredentialRequestMetadataCollection, + LinkSecretColletion, + MessageColletion +} from "@pluto-encrypted/schemas"; + +const Agent = SDK.Agent; +const BasicMessage = SDK.BasicMessage; +const OfferCredential = SDK.OfferCredential; +const ListenerKey = SDK.ListenerKey; +const IssueCredential = SDK.IssueCredential; +const RequestPresentation = SDK.RequestPresentation; + + +export const acceptPresentationRequest = createAsyncThunk< + any, + { + agent: SDK.Agent, + message: SDK.Domain.Message, + credential: SDK.Domain.Credential + } +>("acceptPresentationRequest", async (options, api) => { + try { + const { agent, message, credential } = options; + const requestPresentation = RequestPresentation.fromMessage(message); + try { + const presentation = await agent.createPresentationForRequestProof(requestPresentation, credential); + await agent.sendMessage(presentation.makeMessage()); + } catch (err) { + console.log("continue after err", err); + } + return api.fulfillWithValue(null); + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + +export const rejectPresentationRequest = createAsyncThunk< + any, + { + message: SDK.Domain.Message, + pluto: SDK.Domain.Pluto + } +>("rejectPresentationRequest", async (options, api) => { + try { + const { message, pluto } = options; + const requestPresentation = RequestPresentation.fromMessage(message); + const storedMessage = await pluto.getCollection("messages").findOne({ + selector: { + id: { + $eq: message.id + } + } + }).exec(); + await storedMessage?.remove() + return api.fulfillWithValue(requestPresentation); + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + +export const rejectCredentialOffer = createAsyncThunk< + any, + { + message: SDK.Domain.Message, + pluto: SDK.Domain.Pluto + } +>("rejectCredentialOffer", async (options, api) => { + try { + const { message, pluto } = options; + const credentialOffer = OfferCredential.fromMessage(message); + const storedMessage = await pluto.getCollection("messages").findOne({ + selector: { + id: { + $eq: message.id + } + } + }).exec(); + await storedMessage?.remove() + return api.fulfillWithValue(credentialOffer); + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + +export const acceptCredentialOffer = createAsyncThunk< + any, + { + agent: SDK.Agent, + message: SDK.Domain.Message + } +>("acceptCredentialOffer", async (options, api) => { + try { + const { agent, message } = options; + const credentialOffer = OfferCredential.fromMessage(message); + const requestCredential = await agent.prepareRequestCredentialWithIssuer(credentialOffer); + try { + const requestMessage = requestCredential.makeMessage() + await agent.sendMessage(requestMessage); + } catch (err) { + console.log("continue after err", err); + } + return api.fulfillWithValue(null); + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + + +async function handleMessages( + options: { + dispatch: ThunkDispatch, + agent: SDK.Agent, + }, + newMessages: SDK.Domain.Message[] +) { + const { agent, dispatch } = options; + const issuedCredentials = newMessages.filter((message) => message.piuri === "https://didcomm.org/issue-credential/3.0/issue-credential"); + if (issuedCredentials.length) { + for (const issuedCredential of issuedCredentials) { + const issueCredential = IssueCredential.fromMessage(issuedCredential); + await agent.processIssuedCredentialMessage(issueCredential); + } + } + dispatch( + reduxActions.messageSuccess( + newMessages + ) + ) +} + +export const stopAgent = createAsyncThunk< + { agent: SDK.Agent }, + { agent: SDK.Agent } +>("stopAgent", async (options, api) => { + try { + const { agent } = options + agent.removeListener(ListenerKey.MESSAGE, handleMessages.bind({}, { dispatch: api.dispatch, agent })); + await agent.stop() + return api.fulfillWithValue({ agent }) + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + + +export const startAgent = createAsyncThunk< + { agent: SDK.Agent }, + { agent: SDK.Agent } +>("startAgent", async (options, api) => { + try { + const { agent } = options; + agent.addListener(ListenerKey.MESSAGE, handleMessages.bind({}, { dispatch: api.dispatch, agent })); + await agent.start() + + const mediator = agent.currentMediatorDID; + if (!mediator) { + throw new Error("Mediator not available"); + } + + const secondaryDID = await agent.createNewPeerDID( + [], + true + ); + + const testMessage = new BasicMessage( + { content: "Test Message" }, + secondaryDID, + secondaryDID + ).makeMessage(); + + try { + await agent.sendMessage(testMessage); + } catch (err) { + console.log("Safe to ignore, mediator returns null on successfully receiving the message, unpack fails."); + } + + return api.fulfillWithValue({ agent }) + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + +export const initAgent = createAsyncThunk< + { agent: SDK.Agent }, + { + mediatorDID: SDK.Domain.DID, + pluto: SDK.Domain.Pluto + } +>("initAgent", async (options, api) => { + try { + const { mediatorDID, pluto } = options; + const agent = await Agent.initialize({ mediatorDID, pluto }); + return api.fulfillWithValue({ agent }) + } catch (err) { + return api.rejectWithValue(err as Error); + } +}) + +export const connectDatabase = createAsyncThunk< + { + db: SDK.Domain.Pluto + }, + { + encryptionKey: Uint8Array, + }, + { state: { app: RootState } } +>("connectDatabase", async (options, api) => { + try { + const hashedPassword = sha512(options.encryptionKey) + const db = await Database.createEncrypted<{ + dids: DIDCollection; + didpairs: DIDPairCollection; + mediators: MediatorCollection; + privatekeys: PrivateKeyColletion; + credentials: CredentialCollection; + credentialrequestmetadatas: CredentialRequestMetadataCollection; + linksecrets: LinkSecretColletion; + messages: MessageColletion; + }>( + { + name: DBNAME, + encryptionKey: hashedPassword, + storage: IndexDB, + collections: getDefaultCollections() + } + ); + const messages = await db.getAllMessages() + const connections = await db.getAllDidPairs() + const credentials = await db.getAllCredentials(); + api.dispatch( + reduxActions.dbPreload( + { messages, connections, credentials } + ) + ); + return api.fulfillWithValue({ db }); + } catch (err) { + return api.rejectWithValue(err as Error); + } +}); \ No newline at end of file diff --git a/demos/next/src/actions/types.ts b/demos/next/src/actions/types.ts new file mode 100644 index 000000000..5926175eb --- /dev/null +++ b/demos/next/src/actions/types.ts @@ -0,0 +1,13 @@ +export enum DBConnection { + success = "dbConnectionSuccess", + failure = "dbConnectionFailure", + ongoing = "dbConnectionOngoing", +} + +export enum DBPreload { + complete = "dbPreload", +} + +export enum Message { + success = "messageSuccess" +} diff --git a/demos/next/src/app/App.css b/demos/next/src/app/App.css deleted file mode 100644 index b1009df73..000000000 --- a/demos/next/src/app/App.css +++ /dev/null @@ -1,4 +0,0 @@ -.App { - text-align: center; - padding: 20px 40px; -} diff --git a/demos/next/src/app/Box.tsx b/demos/next/src/app/Box.tsx index 08d561ac8..43704bee1 100644 --- a/demos/next/src/app/Box.tsx +++ b/demos/next/src/app/Box.tsx @@ -4,14 +4,10 @@ import React from "react"; export const Box: React.FC<{ children: React.ReactNode | React.ReactNode[] }> = (props) => { return (
{props.children}
+ ); } \ No newline at end of file diff --git a/demos/next/src/app/globals.css b/demos/next/src/app/globals.css index fd81e8858..4762d8e53 100644 --- a/demos/next/src/app/globals.css +++ b/demos/next/src/app/globals.css @@ -18,10 +18,7 @@ body { color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, + background: linear-gradient(to bottom, transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} + rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb)); +} \ No newline at end of file diff --git a/demos/next/src/app/index.css b/demos/next/src/app/index.css index ec2585e8c..e64b09730 100644 --- a/demos/next/src/app/index.css +++ b/demos/next/src/app/index.css @@ -1,3 +1,131 @@ +@import './globals.css'; + +.content p { + @apply my-6; +} + +.content ul { + @apply my-6; +} + +@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap"); + +html { + font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + + +@keyframes bounce-slow { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-3px); + /* Adjust this value to control the bounce height */ + } +} + +.animate-bounce-slow { + animation: bounce-slow 1.5s ease-in-out infinite; + /* Adjust the animation duration as needed */ +} + +/* #Mega Menu Styles + –––––––––––––––––––––––––––––––––––––––––––––––––– */ +.mega-menu { + display: none; + left: 0; + position: absolute; + text-align: left; + width: 100%; +} + + + +/* #hoverable Class Styles + –––––––––––––––––––––––––––––––––––––––––––––––––– */ +.hoverable { + position: static; +} + +.hoverable>a:after { + content: "\25BC"; + font-size: 10px; + padding-left: 6px; + position: relative; + top: -1px; +} + +.hoverable:hover .mega-menu { + display: block; +} + + +/* #toggle Class Styles + –––––––––––––––––––––––––––––––––––––––––––––––––– */ + +.toggleable>label:after { + content: "\25BC"; + font-size: 10px; + padding-left: 6px; + position: relative; +} + +.toggle-input { + display: none; +} + +.toggle-input:not(checked)~.mega-menu { + display: none; +} + +.toggle-input:checked~.mega-menu { + display: block; +} + +.toggle-input:checked+label { + color: white; + background: #2c5282; + /*@apply bg-blue-800 */ +} + +.toggle-input:checked~label:after { + content: "\25B2"; + font-size: 10px; + padding-left: 6px; + position: relative; + top: -1px; +} + +.loader { + border-top-color: #3498db; + -webkit-animation: spinner 1.5s linear infinite; + animation: spinner 1.5s linear infinite; +} + +@-webkit-keyframes spinner { + 0% { + -webkit-transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(360deg); + } +} + +@keyframes spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', @@ -5,9 +133,9 @@ body { sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + background-color: rgba(16, 24, 40, 1); } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; +} \ No newline at end of file diff --git a/demos/next/src/app/layout.tsx b/demos/next/src/app/layout.tsx index c2f6525f9..c8434c186 100644 --- a/demos/next/src/app/layout.tsx +++ b/demos/next/src/app/layout.tsx @@ -1,8 +1,6 @@ import type { Metadata } from 'next' -import { Inter } from 'next/font/google' + import './globals.css' -import './index.css' -const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { title: 'Create Next App', @@ -16,7 +14,9 @@ export default function RootLayout({ }) { return ( - {children} + + {children} + ) } diff --git a/demos/next/src/app/state.ts b/demos/next/src/app/state.ts deleted file mode 100644 index 3a0622eab..000000000 --- a/demos/next/src/app/state.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { atom } from "jotai"; -import { Domain } from "@atala/prism-wallet-sdk"; - -export const mnemonicsAtom = atom( - undefined -); diff --git a/demos/next/src/components/AgentRequire.tsx b/demos/next/src/components/AgentRequire.tsx new file mode 100644 index 000000000..c99d829c6 --- /dev/null +++ b/demos/next/src/components/AgentRequire.tsx @@ -0,0 +1,41 @@ +import { useMountedApp } from "@/reducers/store"; +import React from "react"; + +export function AgentRequire({ children, text }: { children: any, text?: string }) { + + const { agent } = useMountedApp(); + // Function to recursively clone children with disabled prop set to true + const disableInputs = (child) => { + // If the child is an input element, clone it with disabled prop set to true + if ( + React.isValidElement(child) && + (child.type === 'input' || child.type === 'button') + ) { + return React.cloneElement(child, { disabled: true } as any); + } + // If the child has children, recursively iterate over its children + if (child && child.props && child.props.children) { + return React.cloneElement(child, { + children: React.Children.map(child.props.children, disableInputs) + }); + } + // Otherwise, return the child as is + return child; + }; + + // Clone the children with disabled prop set to true + const disabledChildren = React.Children.map(children, disableInputs); + + + + if (agent && agent.hasStarted) { + return children + } + + return <> + {disabledChildren} +
+ Agent required {text || 'You cannot respond to messages while the agent is not running.'} +
+ +} \ No newline at end of file diff --git a/demos/next/src/components/DBConnect.tsx b/demos/next/src/components/DBConnect.tsx new file mode 100644 index 000000000..76dcf4bcf --- /dev/null +++ b/demos/next/src/components/DBConnect.tsx @@ -0,0 +1,42 @@ +import { useMountedApp } from "@/reducers/store"; +import { useState } from "react"; + +export function DBConnect({ children }) { + function onConnectClick() { + if (!password) { + return + } + return connectDatabase({ + encryptionKey: Buffer.from(password) + }) + } + + const [password, setPassword] = useState("elribonazo") + const { db, connectDatabase } = useMountedApp(); + const isConnected = db.connected; + + if (isConnected) { + return <> + {children} + + } + + return
+

Database connection

+

+ Your database is currently not connected, enter the password and click connect. +

+ { + setPassword(e.target.value) + }} + className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" /> + +
+} \ No newline at end of file diff --git a/demos/next/src/components/Dids.tsx b/demos/next/src/components/Dids.tsx new file mode 100644 index 000000000..d79cb86b8 --- /dev/null +++ b/demos/next/src/components/Dids.tsx @@ -0,0 +1,127 @@ +import React from "react"; +import SDK from "@atala/prism-wallet-sdk"; +import { Box } from "../app/Box"; + +const apollo = new SDK.Apollo(); +const castor = new SDK.Castor(apollo); + + +export function Dids() { + const [prismDid, setPrismDid] = React.useState(null); + const [peerDid, setPeerDid] = React.useState(null); + + const exampleService = new SDK.Domain.Service("didcomm", ["DIDCommMessaging"], { + uri: "https://example.com/endpoint", + accept: ["didcomm/v2"], + routingKeys: ["did:example:somemediator#somekey"], + }); + + async function createPrismDid() { + + const seed = apollo.createSeed(apollo.createRandomMnemonics(), "my-secret"); + const privateKey = apollo.createPrivateKey({ + type: SDK.Domain.KeyTypes.EC, + curve: SDK.Domain.Curve.SECP256K1, + seed: Buffer.from(seed.value).toString("hex"), + }); + + const prismDID = await castor.createPrismDID(privateKey.publicKey(), [ + exampleService, + ]); + + setPrismDid(prismDID); + } + + async function resolvePrismDid() { + if (!prismDid) return; + const didStr = prismDid.toString(); + const didDoc = await castor.resolveDID(didStr); + + console.log("DID DOC", didDoc); + } + + async function createPeerDid() { + + const authPrivateKey = apollo.createPrivateKey({ + type: SDK.Domain.KeyTypes.EC, + curve: SDK.Domain.Curve.ED25519, + }); + + const keyAgreementPrivateKey = apollo.createPrivateKey({ + type: SDK.Domain.KeyTypes.Curve25519, + curve: SDK.Domain.Curve.X25519, + }); + + const peerDID = await castor.createPeerDID( + [authPrivateKey.publicKey(), keyAgreementPrivateKey.publicKey()], + [exampleService] + ); + + setPeerDid(peerDID); + } + + async function resolvePeerDid() { + if (!peerDid) return; + const didStr = peerDid.toString(); + const didDoc = await castor.resolveDID(didStr); + + console.log("DID DOC", didDoc); + } + + return ( + +

+ DIDS +

+ +
+
+
+ + {prismDid ? ( + <> +

+ PRISM DID: + + {prismDid.toString()} +

+
+ + + ) : null} +
+
+
+
+ + {peerDid ? ( + + <> +

+ Peer DID: + {peerDid.toString()} +

+ + + + + + ) : null} +
+
+
+
+ ); +} \ No newline at end of file diff --git a/demos/next/src/components/FooterNavigation.tsx b/demos/next/src/components/FooterNavigation.tsx new file mode 100644 index 000000000..80d43df7d --- /dev/null +++ b/demos/next/src/components/FooterNavigation.tsx @@ -0,0 +1,40 @@ +import Link from "next/link"; + +export function FooterNavigation() { + return ( +
+
+ + +
+
    +
  • + + Edge Agent +
  • +
  • + + Connenctions +
  • +
  • + + Credentials +
  • +
  • + + Messages +
  • +
  • + + Debug + +
  • +
+
+ ) +} diff --git a/demos/next/src/components/Keypair.tsx b/demos/next/src/components/Keypair.tsx new file mode 100644 index 000000000..88928602c --- /dev/null +++ b/demos/next/src/components/Keypair.tsx @@ -0,0 +1,140 @@ + +import { Box } from "@/app/Box"; +import SDK from "@atala/prism-wallet-sdk"; +import React from "react"; +import * as jose from "jose"; +import { trimString } from "../app/utils"; + +const apollo = new SDK.Apollo(); + +function Signatures({ keyPair }: { keyPair: SDK.Domain.KeyPair; }) { + const [originalText, setOriginalText] = React.useState("Random text"); + const [signatureEncoded, setSignatureEncoded] = React.useState(undefined); + const [isSignatureValid, setIsSignatureValid] = React.useState(undefined); + + function signData() { + if (keyPair.privateKey.isSignable()) { + const helloWorldSig = keyPair.privateKey.sign(originalText); + setSignatureEncoded(jose.base64url.encode(helloWorldSig)); + } + } + + function verifySignature() { + if (!signatureEncoded) return; + + let isValid; + + try { + if (keyPair.publicKey.canVerify()) { + isValid = keyPair.publicKey.verify(originalText, Buffer.from(jose.base64url.decode(signatureEncoded))); + } + + } catch (e) { + console.warn("Failed to validate signature", e); + isValid = false; + } + + setIsSignatureValid(isValid); + } + + if (keyPair.curve === SDK.Domain.Curve.X25519) { + return Signatures not supported for X25519 keys!; + } + + return ( + +

+ + Operations + +

+
+
+ + + + +