diff --git a/.changeset/early-wolves-fix.md b/.changeset/early-wolves-fix.md
new file mode 100644
index 00000000..2fa5a631
--- /dev/null
+++ b/.changeset/early-wolves-fix.md
@@ -0,0 +1,60 @@
+---
+"@spruceid/ssx-core": major
+"@spruceid/ssx-gnosis-extension": patch
+"@spruceid/ssx-react": patch
+"@spruceid/ssx": patch
+"@spruceid/ssx-server": patch
+"@spruceid/ssx-serverless": patch
+---
+
+Refactor code to avoid duplication and improve performance.
+
+## General changes:
+- Creates a main `tsconfig` file to be extended by packages;
+- Configures `ssx-core`as a new package on the monorepo;
+- Removes duplicate `@changesets/cli` dependency.
+
+## @spruceid/ssx-core creation:
+- This package was created to held the types definitions and utils functions to all packages. This reduces the amount of duplicated code, prevent circular dependencies, reduces package sizes (tree-shaking during transpilation), and ensures that changes to the API will need a bump to this new package.
+- To unify the packages some interfaces/types names were updated:
+ - `@spruceid/ssx-sdk`: `SSXConfig` -> `SSXClientConfig`;
+ - `@spruceid/ssx-sdk`: `SSXProviders` -> `SSXClientProviders`;
+ - `@spruceid/ssx-sdk`: `SSXSession` -> `SSXClientSession`;
+ - `@spruceid/ssx-server`: `SSXConfig` -> `SSXServerConfig`;
+ - `@spruceid/ssx-server`: `SSXProviders` -> `SSXServerProviders`;
+
+## @spruceid/ssx changes:
+- Adds `@spruceid/ssx-core` as a dependency;
+- Removes all types and interfaces declarations. They were moved to `ssx-core`;
+- Exports `SSXConfig` (deprecated) and `SSXClientConfig`;
+- Exports `SSXProviders` (deprecated) and `SSXClientProviders`;
+- Exports `SSXSession` (deprecated) and `SSXClientSession`;
+- Removes all utils functions. They were moved to `ssx-core`;
+- Optimizes `try/catch` blocks;
+- Updates `examples/ssx-test-dapp` to support ENS resolution from `examples/ssx-test-serverless-dynamodb-api`.
+
+## @spruceid/ssx-react changes:
+- Updates `ssxConfig?: SSXConfig;` on `SSXProviderProps` to `ssxConfig?: SSXClientConfig;` (non breaking change).
+
+## @spruceid/ssx-gnosis-extension changes:
+- Adds `@spruceid/ssx-core` as a dependency;
+- Adds types from `ssx-core` to all SSX related variables;
+- Optimizes `try/catch` blocks.
+
+## @spruceid/ssx-server changes:
+- Adds `@spruceid/ssx-core` as a dependency;
+- Removes all types and interfaces declarations. They were moved to `ssx-core`;
+- Exports `SSXConfig` (deprecated) and `SSXServerConfig`;
+- Exports `SSXProviders` (deprecated) and `SSXServerProviders`;
+- Removes all utils functions. They were moved to `ssx-core`;
+- Optimizes `try/catch` blocks.
+
+## @spruceid/ssx-serverless changes:
+- Adds `@spruceid/ssx-core` as a dependency;
+- Removes some types and interfaces declarations. They were moved to `ssx-core`;
+- Removes all utils functions. They were moved to `ssx-core`;
+- Optimizes `try/catch` blocks;
+- Changes axios version to `"^0.27.2"`;
+- Updates `examples/ssx-test-serverless-dynamodb-api` to resolve ENS accorddly with the request params and fixes the `/ssx-login` JSON response.
+
+
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 00000000..c1da59be
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,39 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true,
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:prettier/recommended",
+ ],
+ "ignorePatterns": [
+ "examples/",
+ "packages/create-ssx-dapp/",
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaVersion": "latest",
+ "sourceType": "module",
+ "project": ["./tsconfig.json", "./packages/*/tsconfig.json"],
+ },
+ "plugins": [
+ "@typescript-eslint",
+ ],
+ "root": true,
+ "rules": {
+ "object-property-newline": "error",
+ "import/prefer-default-export": "off",
+ "no-promise-executor-return": "warn",
+ "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
+ "no-use-before-define": "warn",
+ "import/extensions": "off",
+ "import/no-unresolved": "off",
+ "max-len": "warn",
+ "max-classes-per-file": "off",
+ "no-plusplus": "off",
+ "no-await-in-loop": "off",
+ "@typescript-eslint/no-empty-interface": "off",
+ },
+}
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..ab06c3b4
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "semi": true,
+ "singleQuote": true,
+ "arrowParens": "avoid",
+ "bracketSameLine": true,
+ "printWidth": 80,
+ "tabWidth": 2,
+ "useTabs": false,
+ "endOfLine": "lf"
+}
\ No newline at end of file
diff --git a/examples/ssx-test-dapp/src/App.js b/examples/ssx-test-dapp/src/App.js
index 30053adf..63fa501e 100644
--- a/examples/ssx-test-dapp/src/App.js
+++ b/examples/ssx-test-dapp/src/App.js
@@ -18,7 +18,10 @@ function AccountInfo({ address, session }) {
{
session?.ens &&
- (session?.ens.domain || session?.ens.avatarUrl) ?
+ (
+ session?.ens.domain || session?.ens.avatarUrl ||
+ session?.ens.ensName || session?.ens.ensAvatarUrl
+ ) ?
ENS
@@ -26,18 +29,18 @@ function AccountInfo({ address, session }) {
{
- session.ens.avatarUrl ?
+ session.ens.avatarUrl || session.ens.ensAvatarUrl ?
:
null
}
{
- session.ens.domain ?
+ session.ens.domain || session.ens.ensName ?
- {session.ens.domain}
+ {session.ens.domain || session.ens.ensName}
:
null
}
diff --git a/examples/ssx-test-serverless-dynamodb-api/src/libs/siwe.ts b/examples/ssx-test-serverless-dynamodb-api/src/libs/siwe.ts
index 09b8c934..8eacc287 100644
--- a/examples/ssx-test-serverless-dynamodb-api/src/libs/siwe.ts
+++ b/examples/ssx-test-serverless-dynamodb-api/src/libs/siwe.ts
@@ -77,10 +77,11 @@ const signIn: ValidatedEventAPIGatewayProxyEvent
= async (e
event.body.walletAddress,
{
daoLogin: true,
- resolveEnsDomain: true,
- resolveEnsAvatar: true,
+ resolveEnsDomain: (event.body.resolveEns as any).domain ?? false,
+ resolveEnsAvatar: (event.body.resolveEns as any).avatar ?? false,
}
)
+ .then((response) => formatJSONResponse(200, { ...response }))
.catch(error => formatJSONResponse(500, { error }));
};
diff --git a/package.json b/package.json
index 7496214c..e16998e9 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,8 @@
"clean": "lerna run clean",
"ci": "npm install && npm test",
"test": "lerna run test",
+ "lint": "eslint . --ignore-path .gitignore --ext .ts,.tsx,.js",
+ "lint:fix": "yarn lint --fix",
"documentation": "lerna run doc && yarn documentation:reference",
"documentation:reference": "node scripts/build-docs.js",
"bootstrap": "lerna bootstrap",
@@ -27,6 +29,7 @@
"gnosis": "yarn workspace @spruceid/ssx-gnosis-extension",
"sdk": "yarn workspace @spruceid/ssx",
"react": "yarn workspace @spruceid/ssx-react",
+ "core": "yarn workspace @spruceid/ssx-core",
"server": "yarn workspace @spruceid/ssx-server",
"serverless": "yarn workspace @spruceid/ssx-serverless",
"test-dapp": "yarn workspace ssx-test-dapp",
@@ -38,11 +41,14 @@
"devDependencies": {
"@changesets/cli": "^2.25.0",
"concurrently": "^7.3.0",
+ "eslint": "^8.28.0",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-prettier": "^4.2.1",
"lerna": "^5.1.2",
"nx": "^14.5.4",
"rimraf": "^3.0.2",
- "yarn": "^1.22.19",
"typescript": "^4.8.4",
- "@changesets/cli": "^2.25.0"
+ "yarn": "^1.22.19"
}
}
diff --git a/packages/ssx-core/.eslintrc b/packages/ssx-core/.eslintrc
new file mode 100644
index 00000000..21758ea0
--- /dev/null
+++ b/packages/ssx-core/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "extends": [
+ "../../.eslintrc"
+ ]
+}
diff --git a/packages/ssx-core/README.md b/packages/ssx-core/README.md
new file mode 100644
index 00000000..03b52573
--- /dev/null
+++ b/packages/ssx-core/README.md
@@ -0,0 +1,13 @@
+# SSX-Core
+
+SSX-Core is a library made to aggregate types and utils to other SSX packages.
+
+## Installation
+
+You can add SSX-Core from yarn or npm:
+
+```bash
+npm install @spruceid/ssx-core
+# or
+yarn add @spruceid/ssx-core
+```
diff --git a/packages/ssx-core/api-documenter.json b/packages/ssx-core/api-documenter.json
new file mode 100644
index 00000000..4c1e8d36
--- /dev/null
+++ b/packages/ssx-core/api-documenter.json
@@ -0,0 +1,10 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-documenter.schema.json",
+ "outputTarget": "markdown",
+ "tableOfContents": {
+ "nonEmptyCategoryNodeNames": ["References", "Interface6"],
+ "catchAllCategory": "References",
+ "categorizeByName": true,
+ "categoryInlineTag": "docCategory"
+ }
+ }
\ No newline at end of file
diff --git a/packages/ssx-core/api-extractor.json b/packages/ssx-core/api-extractor.json
new file mode 100644
index 00000000..c70e9a82
--- /dev/null
+++ b/packages/ssx-core/api-extractor.json
@@ -0,0 +1,392 @@
+/**
+ * Config file for API Extractor. For more info, please visit: https://api-extractor.com
+ */
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
+
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for
+ * standard settings to be shared across multiple projects.
+ *
+ * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
+ * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
+ * resolved using NodeJS require().
+ *
+ * SUPPORTED TOKENS: none
+ * DEFAULT VALUE: ""
+ */
+ // "extends": "./shared/api-extractor-base.json"
+ // "extends": "my-package/include/api-extractor-base.json"
+
+ /**
+ * Determines the "" token that can be used with other config file settings. The project folder
+ * typically contains the tsconfig.json and package.json config files, but the path is user-defined.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting.
+ *
+ * The default value for "projectFolder" is the token "", which means the folder is determined by traversing
+ * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
+ * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
+ * will be reported.
+ *
+ * SUPPORTED TOKENS:
+ * DEFAULT VALUE: ""
+ */
+ // "projectFolder": "..",
+
+ /**
+ * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
+ * analyzes the symbols exported by this module.
+ *
+ * The file extension must be ".d.ts" and not ".ts".
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ */
+ "mainEntryPointFilePath": "/dist/index.d.ts",
+
+ /**
+ * A list of NPM package names whose exports should be treated as part of this package.
+ *
+ * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1",
+ * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part
+ * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly
+ * imports library2. To avoid this, we can specify:
+ *
+ * "bundledPackages": [ "library2" ],
+ *
+ * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
+ * local files for library1.
+ */
+ "bundledPackages": [],
+
+ /**
+ * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
+ * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
+ * To use the OS's default newline kind, specify "os".
+ *
+ * DEFAULT VALUE: "crlf"
+ */
+ // "newlineKind": "crlf",
+
+ /**
+ * Set to true when invoking API Extractor's test harness. When `testMode` is true, the `toolVersion` field in the
+ * .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests.
+ *
+ * DEFAULT VALUE: "false"
+ */
+ // "testMode": false,
+
+ /**
+ * Specifies how API Extractor sorts members of an enum when generating api.json. By default, the output files
+ * will be sorted alphabetically, which is "by-name". To keep the ordering in the source code, specify "preserve".
+ *
+ * DEFAULT VALUE: "by-name"
+ */
+ // enumMemberOrder?: EnumMemberOrder,
+
+ /**
+ * Determines how the TypeScript compiler engine will be invoked by API Extractor.
+ */
+ "compiler": {
+ /**
+ * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * Note: This setting will be ignored if "overrideTsconfig" is used.
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: "/tsconfig.json"
+ */
+ "tsconfigFilePath": "/tsconfig.json"
+ /**
+ * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
+ * The object must conform to the TypeScript tsconfig schema:
+ *
+ * http://json.schemastore.org/tsconfig
+ *
+ * If omitted, then the tsconfig.json file will be read from the "projectFolder".
+ *
+ * DEFAULT VALUE: no overrideTsconfig section
+ */
+ // "overrideTsconfig": {
+ // . . .
+ // }
+ /**
+ * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
+ * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when
+ * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses
+ * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck.
+ *
+ * DEFAULT VALUE: false
+ */
+ // "skipLibCheck": true,
+ },
+
+ /**
+ * Configures how the API report file (*.api.md) will be generated.
+ */
+ "apiReport": {
+ /**
+ * (REQUIRED) Whether to generate an API report.
+ */
+ "enabled": true,
+
+ /**
+ * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce
+ * a full file path.
+ *
+ * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/".
+ *
+ * SUPPORTED TOKENS: ,
+ * DEFAULT VALUE: ".api.md"
+ */
+ // "reportFileName": ".api.md",
+
+ /**
+ * Specifies the folder where the API report file is written. The file name portion is determined by
+ * the "reportFileName" setting.
+ *
+ * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
+ * e.g. for an API review.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: "/temp/"
+ */
+ "reportFolder": "/temp/",
+
+ /**
+ * Specifies the folder where the temporary report file is written. The file name portion is determined by
+ * the "reportFileName" setting.
+ *
+ * After the temporary file is written to disk, it is compared with the file in the "reportFolder".
+ * If they are different, a production build will fail.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: "/temp/"
+ */
+ // "reportTempFolder": "/temp/"
+ },
+
+ /**
+ * Configures how the doc model file (*.api.json) will be generated.
+ */
+ "docModel": {
+ /**
+ * (REQUIRED) Whether to generate a doc model file.
+ */
+ "enabled": true
+
+ /**
+ * The output path for the doc model file. The file extension should be ".api.json".
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: "/temp/.api.json"
+ */
+ // "apiJsonFilePath": "/temp/.api.json"
+ },
+
+ /**
+ * Configures how the .d.ts rollup file will be generated.
+ */
+ "dtsRollup": {
+ /**
+ * (REQUIRED) Whether to generate the .d.ts rollup file.
+ */
+ "enabled": true
+
+ /**
+ * Specifies the output path for a .d.ts rollup file to be generated without any trimming.
+ * This file will include all declarations that are exported by the main entry point.
+ *
+ * If the path is an empty string, then this file will not be written.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: "/dist/.d.ts"
+ */
+ // "untrimmedFilePath": "/dist/.d.ts",
+
+ /**
+ * Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release.
+ * This file will include only declarations that are marked as "@public", "@beta", or "@alpha".
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: ""
+ */
+ // "alphaTrimmedFilePath": "/dist/-alpha.d.ts",
+
+ /**
+ * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
+ * This file will include only declarations that are marked as "@public" or "@beta".
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: ""
+ */
+ // "betaTrimmedFilePath": "/dist/-beta.d.ts",
+
+ /**
+ * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
+ * This file will include only declarations that are marked as "@public".
+ *
+ * If the path is an empty string, then this file will not be written.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: ""
+ */
+ // "publicTrimmedFilePath": "/dist/-public.d.ts",
+
+ /**
+ * When a declaration is trimmed, by default it will be replaced by a code comment such as
+ * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
+ * declaration completely.
+ *
+ * DEFAULT VALUE: false
+ */
+ // "omitTrimmingComments": true
+ },
+
+ /**
+ * Configures how the tsdoc-metadata.json file will be generated.
+ */
+ "tsdocMetadata": {
+ /**
+ * Whether to generate the tsdoc-metadata.json file.
+ *
+ * DEFAULT VALUE: true
+ */
+ // "enabled": true,
+ /**
+ * Specifies where the TSDoc metadata file should be written.
+ *
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
+ * prepend a folder token such as "".
+ *
+ * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata",
+ * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup
+ * falls back to "tsdoc-metadata.json" in the package folder.
+ *
+ * SUPPORTED TOKENS: , ,
+ * DEFAULT VALUE: ""
+ */
+ // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json"
+ },
+
+ /**
+ * Configures how API Extractor reports error and warning messages produced during analysis.
+ *
+ * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages.
+ */
+ "messages": {
+ /**
+ * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing
+ * the input .d.ts files.
+ *
+ * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551"
+ *
+ * DEFAULT VALUE: A single "default" entry with logLevel=warning.
+ */
+ "compilerMessageReporting": {
+ /**
+ * Configures the default routing for messages that don't match an explicit rule in this table.
+ */
+ "default": {
+ /**
+ * Specifies whether the message should be written to the the tool's output log. Note that
+ * the "addToApiReportFile" property may supersede this option.
+ *
+ * Possible values: "error", "warning", "none"
+ *
+ * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail
+ * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes
+ * the "--local" option), the warning is displayed but the build will not fail.
+ *
+ * DEFAULT VALUE: "warning"
+ */
+ "logLevel": "warning"
+
+ /**
+ * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md),
+ * then the message will be written inside that file; otherwise, the message is instead logged according to
+ * the "logLevel" option.
+ *
+ * DEFAULT VALUE: false
+ */
+ // "addToApiReportFile": false
+ }
+
+ // "TS2551": {
+ // "logLevel": "warning",
+ // "addToApiReportFile": true
+ // },
+ //
+ // . . .
+ },
+
+ /**
+ * Configures handling of messages reported by API Extractor during its analysis.
+ *
+ * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag"
+ *
+ * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings
+ */
+ "extractorMessageReporting": {
+ "default": {
+ "logLevel": "none"
+ // "addToApiReportFile": false
+ }
+
+ // "ae-extra-release-tag": {
+ // "logLevel": "none",
+ // "addToApiReportFile": false
+ // }
+ //
+ // . . .
+ },
+
+ /**
+ * Configures handling of messages reported by the TSDoc parser when analyzing code comments.
+ *
+ * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text"
+ *
+ * DEFAULT VALUE: A single "default" entry with logLevel=warning.
+ */
+ "tsdocMessageReporting": {
+ "default": {
+ "logLevel": "warning"
+ // "addToApiReportFile": false
+ }
+
+ // "tsdoc-link-tag-unescaped-text": {
+ // "logLevel": "warning",
+ // "addToApiReportFile": true
+ // },
+ //
+ // . . .
+ }
+ }
+}
diff --git a/packages/ssx-core/package.json b/packages/ssx-core/package.json
new file mode 100644
index 00000000..f0d57975
--- /dev/null
+++ b/packages/ssx-core/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@spruceid/ssx-core",
+ "version": "1.0.0",
+ "description": "SSX core library",
+ "author": "Spruce Systems Inc.",
+ "license": "Apache-2.0 OR MIT",
+ "homepage": "https://github.com/spruceid/ssx/packages/ssx-core#readme",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "bugs": {
+ "url": "https://github.com/spruceid/ssx/issues"
+ },
+ "directories": {
+ "src": "src"
+ },
+ "scripts": {
+ "build": "tsc",
+ "doc": "yarn doc:extractor && yarn doc:documenter",
+ "doc:extractor": "api-extractor run",
+ "doc:documenter": "api-documenter generate -i temp -o ../../documentation/reference/ssx-core"
+ },
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/spruceid/ssx.git"
+ },
+ "dependencies": {
+ "axios": "^0.27.2",
+ "express": "^4.18.1",
+ "express-session": "^1.17.3",
+ "siwe": "^2.1.2"
+ },
+ "devDependencies": {
+ "@microsoft/api-documenter": "^7.19.4",
+ "@microsoft/api-extractor": "^7.29.2",
+ "@typescript-eslint/eslint-plugin": "^5.23.0",
+ "@typescript-eslint/parser": "^5.23.0",
+ "eslint": "^8.15.0",
+ "eslint-config-prettier": "^8.5.0",
+ "prettier": "^2.6.2",
+ "ethers": "^5.6.8"
+ },
+ "peerDependencies": {
+ "ethers": "^5.6.8"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/packages/ssx-core/src/client/index.ts b/packages/ssx-core/src/client/index.ts
new file mode 100644
index 00000000..fcdac2de
--- /dev/null
+++ b/packages/ssx-core/src/client/index.ts
@@ -0,0 +1 @@
+export * from './types';
\ No newline at end of file
diff --git a/packages/ssx-core/src/client/types.ts b/packages/ssx-core/src/client/types.ts
new file mode 100644
index 00000000..e5aae508
--- /dev/null
+++ b/packages/ssx-core/src/client/types.ts
@@ -0,0 +1,131 @@
+/* eslint-disable no-shadow */
+import { ssxSession } from '@spruceid/ssx-sdk-wasm';
+import { AxiosInstance } from 'axios';
+import { ethers } from 'ethers';
+import { SSXEnsData, SSXEnsResolveOptions, SSXRPCProvider } from '../types';
+
+/** Core config for SSX. */
+export interface SSXClientConfig {
+ /** Whether or not daoLogin is enabled. */
+ enableDaoLogin?: boolean;
+ /** Connection to a cryptographic keypair and/or network. */
+ providers?: SSXClientProviders;
+ /** Optional session configuration for the SIWE message. */
+ siweConfig?: SiweConfig;
+ /** Whether or not ENS resolution is enabled. True means resolve all on client. */
+ resolveEns?: boolean | SSXEnsConfig;
+}
+
+/** Representation of an active SSXSession. */
+export type SSXClientSession = {
+ /** User address */
+ address: string;
+ /** User address without delegation */
+ walletAddress: string;
+ chainId: number;
+ /** Key to identify the session */
+ sessionKey: string;
+ /** The message that can be obtained by SiweMessage.prepareMessage() */
+ siwe: string;
+ /** The signature of the siwe message */
+ signature: string;
+ /** ENS data supported by SSX */
+ ens?: SSXEnsData;
+};
+
+/** The URL of the server running ssx-server. Providing this field enables SIWE server communication */
+export type SSXServerHost = string;
+
+/** The ssx-powered server configuration settings */
+export type SSXProviderServer = {
+ host: SSXServerHost;
+};
+
+/** Web3 provider configuration settings */
+export interface SSXProviderWeb3 {
+ /**
+ * window.ethereum for Metamask;
+ * web3modal.connect() for Web3Modal;
+ * const signer = useSigner(); const provider = signer.provider; from Wagmi for Rainbowkit
+ * */
+ driver: any;
+}
+
+/** SSX web3 configuration settings */
+export interface SSXClientProviders {
+ /** Web3 wallet provider */
+ web3?: SSXProviderWeb3;
+ /** JSON RPC provider configurations */
+ rpc?: SSXRPCProvider;
+ /** Optional reference to server running ssx-server.
+ * Providing this field enables communication with ssx-server */
+ server?: SSXProviderServer;
+}
+
+
+/** Optional session configuration for the SIWE message. */
+export interface SiweConfig extends Partial { }
+
+/** Extra SIWE fields. */
+export type ExtraFields = ssxSession.ExtraFields;
+
+/** Overrides for the session configuration. */
+export type ConfigOverrides = {
+ siwe?: SiweConfig
+};
+
+/** ENS options supported by SSX. */
+export interface SSXEnsConfig {
+ /** Enable the ENS resolution on server instead of on client. */
+ resolveOnServer?: boolean;
+ /** ENS resolution options. True means resolve all. */
+ resolve: SSXEnsResolveOptions;
+}
+
+/** Interface to an intermediate SSX state: connected, but not signed-in. */
+export interface ISSXConnected {
+ /** Instance of SSXSessionBuilder. */
+ builder: ssxSession.SSXSessionBuilder;
+ /** SSXConfig object. */
+ config: SSXClientConfig;
+ /** List of enabled extensions. */
+ extensions: SSXExtension[];
+ /** Web3 provider. */
+ provider: ethers.providers.Web3Provider;
+ /** Promise that is initialized on construction to run the "afterConnect" methods of extensions. */
+ afterConnectHooksPromise: Promise;
+ /** Method to verify if extension is enabled. */
+ isExtensionEnabled: (namespace: string) => boolean;
+ /** Axios instance. */
+ api?: AxiosInstance;
+ /** Method to apply the "afterConnect" methods and the delegated capabilities of the extensions. */
+ applyExtensions: () => Promise;
+ /** Method to apply the "afterSignIn" methods of the extensions. */
+ afterSignIn: (session: SSXClientSession) => Promise;
+ /** Method to request nonce from server. */
+ ssxServerNonce: (params: Record) => Promise;
+ /** Method to request sign in from server and return session. */
+ ssxServerLogin: (session: SSXClientSession) => Promise;
+ /** Method to request the user to sign in. */
+ signIn: () => Promise;
+ /** Method to request the user to sign out. */
+ signOut: (session: SSXClientSession) => Promise
+}
+
+/** Interface for an extension to SSX. */
+export interface SSXExtension {
+ /** [recap] Capability namespace. */
+ namespace?: string,
+ /** [recap] Default delegated actions in capability namespace. */
+ defaultActions?(): Promise,
+ /** [recap] Delegated actions by target in capability namespace. */
+ targetedActions?(): Promise<{ [target: string]: string[] }>,
+ /** [recap] Extra metadata to help validate the capability. */
+ extraFields?(): Promise,
+ /** Hook to run after SSX has connected to the user's wallet.
+ * This can return an object literal to override the session configuration before the user
+ * signs in. */
+ afterConnect?(ssx: ISSXConnected): Promise;
+ /** Hook to run after SSX has signed in. */
+ afterSignIn?(session: SSXClientSession): Promise,
+}
diff --git a/packages/ssx-core/src/index.ts b/packages/ssx-core/src/index.ts
new file mode 100644
index 00000000..e5481a44
--- /dev/null
+++ b/packages/ssx-core/src/index.ts
@@ -0,0 +1,4 @@
+export * from './types';
+export * from './utils';
+export * from './client';
+export * from './server';
\ No newline at end of file
diff --git a/packages/ssx-core/src/server/index.ts b/packages/ssx-core/src/server/index.ts
new file mode 100644
index 00000000..f0c4eaa5
--- /dev/null
+++ b/packages/ssx-core/src/server/index.ts
@@ -0,0 +1,2 @@
+export * from './utils';
+export * from './types';
diff --git a/packages/ssx-core/src/server/types.ts b/packages/ssx-core/src/server/types.ts
new file mode 100644
index 00000000..a629d241
--- /dev/null
+++ b/packages/ssx-core/src/server/types.ts
@@ -0,0 +1,91 @@
+import { CookieOptions } from 'express';
+import { SessionOptions, Store } from 'express-session';
+import { SSXRPCProvider } from '../types';
+
+
+/** Configuration interface for ssx-server */
+export interface SSXServerConfig {
+ /** A key used for signing cookies coming from the server. Providing this key enables signed cookies. */
+ signingKey?: string;
+ /** Connection to a cryptographic keypair and/or network. */
+ providers?: SSXServerProviders;
+ /** Changes cookie attributes. Determines whether or not server cookies
+ * require HTTPS and sets the SameSite attribute to 'lax'. Defaults to false */
+ useSecureCookies?: boolean;
+}
+
+/** SSX web3 configuration settings. */
+export interface SSXServerProviders {
+ /** JSON RPC provider configurations. */
+ rpc?: SSXRPCProvider;
+ /** SSX Session Store configuration settings. */
+ sessionConfig?: Partial;
+ /** Metrics service configurations. */
+ metrics?: SSXMetricsProvider;
+}
+
+/** SSX Session Store configuration settings */
+export interface SSXSessionStoreConfig {
+ /** Overrides for [SessionOptions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a24d35afe48f7fb702e7617b983ddca1904ba36b/types/express-session/index.d.ts#L52) */
+ sessionOptions?: Partial;
+ /** Connector for different stores */
+ store?: (session: any) => Store;
+}
+
+/** SSX Redis Session Store Provider settings. */
+export type SSXRedisSessionStoreProvider = {
+ service: 'redis';
+ redisUrl: string;
+};
+
+/** SSX Express Session Store Provider settings. */
+export type SSXExpressSessionStoreProvider = {
+ service: 'express';
+ config?: SessionOptions;
+};
+
+/** SSX Metrics Provider settings. */
+export type SSXMetricsProvider = {
+ service: 'ssx';
+ apiKey: string;
+};
+
+/** Configuration interface for cookies issued by ssx-server */
+export interface SSXCookieOptions extends CookieOptions {
+ /** Prevents client-side javascript from accessing cookies. Should always be true. */
+ httpOnly: true;
+ /** Whether or not cookies should be sent over https. Recommend true for production. */
+ secure: boolean;
+ /** Prevents Cross Site Request Forgery Attacks by telling the browser to only send
+ * cookies with request from your site. The lax setting allows GET requests from
+ * other sites. Recommended true for production. */
+ sameSite: boolean | 'lax' | 'strict' | 'none' | undefined;
+ /** Whether or not cookies should be signed. Recommended true for production.
+ * Set to true by providing a signing key. If false, cookies can be tampered
+ * with on the client. */
+ signed: boolean;
+}
+
+/** Allowed fields for an SSX Log. */
+export interface SSXLogFields {
+ /** Unique identifier for the user, formatted as a DID. */
+ userId: string;
+ /** RFC-3339 time of resource generation, defaults to now. */
+ timestamp?: string;
+ /** Type of content being logged. */
+ type: SSXEventLogTypes;
+ /** Any JSON stringifiable structure to be logged. */
+ content: string | Record;
+}
+
+/** Available SSX Log Types. */
+export enum SSXEventLogTypes {
+ /** Login type definition. */
+ LOGIN = 'ssx-login',
+ /** Logout type definition. */
+ // LOGOUT = "ssx-logout",
+ /** Logging type definition. */
+ // LOG = "LOG",
+ /** Event type definition. */
+ // EVENT = "event",
+}
\ No newline at end of file
diff --git a/packages/ssx-core/src/server/utils.ts b/packages/ssx-core/src/server/utils.ts
new file mode 100644
index 00000000..d1b4ff94
--- /dev/null
+++ b/packages/ssx-core/src/server/utils.ts
@@ -0,0 +1,42 @@
+import { AxiosInstance } from "axios";
+import { SSXLogFields } from "./types";
+
+/**
+ * Abstracts the fetch API to append correct headers, host and parse
+ * responses to JSON for POST requests.
+ * @param api - Axios Instance.
+ * @param route - Request route.
+ * @param body - Request body.
+ * @returns True (success) or false (error).
+ */
+export const ssxPost = (
+ api: AxiosInstance,
+ route: string,
+ body: any
+): Promise => {
+ return api
+ .post(route, typeof body === 'string' ? body : JSON.stringify(body))
+ .then((res: any) => res.status === 204)
+ .catch((e: any) => {
+ console.error(e);
+ return false;
+ });
+};
+
+/**
+ * Registers a new event to the API.
+ * @param api - Axios Instance.
+ * @param apiKey - SSX Platform API Key.
+ * @param data - SSXLogFields to log.
+ * @returns True (success) or false (error).
+ */
+export const ssxLog = async (
+ api: AxiosInstance,
+ apiKey: string,
+ data: SSXLogFields
+): Promise => {
+ if (!data.timestamp) data.timestamp = new Date().toISOString();
+ return (
+ Boolean(apiKey) && ssxPost(api, '/events', data)
+ );
+};
\ No newline at end of file
diff --git a/packages/ssx-server/src/types.ts b/packages/ssx-core/src/types.ts
similarity index 50%
rename from packages/ssx-server/src/types.ts
rename to packages/ssx-core/src/types.ts
index eb3285ac..f83bb1f9 100644
--- a/packages/ssx-server/src/types.ts
+++ b/packages/ssx-core/src/types.ts
@@ -1,30 +1,7 @@
import { providers } from 'ethers';
import { ConnectionInfo } from 'ethers/lib/utils';
-import { CookieOptions } from 'express';
-import { SessionOptions, Store } from 'express-session';
-
-/** Configuration interface for ssx-server */
-export interface SSXServerConfig {
- /** A key used for signing cookies coming from the server. Providing this key enables signed cookies. */
- signingKey?: string;
- /** Connection to a cryptographic keypair and/or network. */
- providers?: SSXProviders;
- /** Changes cookie attributes. Determines whether or not server cookies
- * require HTTPS and sets the SameSite attribute to 'lax'. Defaults to false */
- useSecureCookies?: boolean;
-}
-
-/** SSX web3 configuration settings */
-export interface SSXProviders {
- /** JSON RPC provider configurations */
- rpc?: SSXRPCProvider;
- // TODO(w4ll3): doc
- /** */
- sessionConfig?: Partial;
- /** Metrics service configurations */
- metrics?: SSXMetricsProvider;
-}
+/** Supported provider types. */
export type SSXRPCProvider =
| SSXGenericProvider
| SSXEtherscanProvider
@@ -35,7 +12,7 @@ export type SSXRPCProvider =
| SSXAnkrProvider
| SSXCustomProvider;
-/** Enum of supported RPC providers */
+/** Enum of supported EthersJS providers. */
export enum SSXRPCProviders {
SSXAlchemyProvider = 'alchemy',
SSXAnkrProvider = 'ankr',
@@ -46,7 +23,7 @@ export enum SSXRPCProviders {
SSXPocketProvider = 'pocket',
}
-/** Enum of supported networks for Etherscan */
+/** Enum of supported networks for Etherscan. */
export enum SSXEtherscanProviderNetworks {
MAINNET = 'homestead',
ROPSTEN = 'ropsten',
@@ -55,18 +32,18 @@ export enum SSXEtherscanProviderNetworks {
KOVAN = 'kovan',
}
-/** Etherscan provider settings */
+/** Etherscan provider settings. */
export type SSXEtherscanProvider = {
service: SSXRPCProviders.SSXEtherscanProvider;
apiKey?: string;
network?: SSXEtherscanProviderNetworks;
};
-/* Type-Guard for SSXEtherScanProvider */
+/* Type-Guard for SSXEtherScanProvider. */
export const isSSXEtherscanProvider = (provider: SSXRPCProvider):
provider is SSXEtherscanProvider => provider.service === SSXRPCProviders.SSXEtherscanProvider;
-/** Enum of supported networks for Infura */
+/** Enum of supported networks for Infura. */
export enum SSXInfuraProviderNetworks {
MAINNET = 'homestead',
ROPSTEN = 'ropsten',
@@ -81,24 +58,24 @@ export enum SSXInfuraProviderNetworks {
ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
}
-/** Infura provider project settings */
+/** Infura provider project settings. */
export type SSXInfuraProviderProjectSettings = {
projectId: string;
projectSecret: string;
};
-/** Infura provider settings */
+/** Infura provider settings. */
export type SSXInfuraProvider = {
service: SSXRPCProviders.SSXInfuraProvider;
apiKey: string | SSXInfuraProviderProjectSettings;
network?: SSXInfuraProviderNetworks;
};
-/* Type-Guard for SSXInfuraProvider */
+/* Type-Guard for SSXInfuraProvider. */
export const isSSXInfuraProvider = (provider: SSXRPCProvider):
provider is SSXInfuraProvider => provider.service === SSXRPCProviders.SSXInfuraProvider;
-/** Enum of supported networks for Alchemy */
+/** Enum of supported networks for Alchemy. */
export enum SSXAlchemyProviderNetworks {
MAINNET = 'homestead',
ROPSTEN = 'ropsten',
@@ -113,27 +90,27 @@ export enum SSXAlchemyProviderNetworks {
ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
}
-/** Alchemy provider settings */
+/** Alchemy provider settings. */
export type SSXAlchemyProvider = {
service: SSXRPCProviders.SSXAlchemyProvider;
apiKey?: string;
network?: SSXAlchemyProviderNetworks;
};
-/* Type-Guard for SSXAlchemyProvider */
+/* Type-Guard for SSXAlchemyProvider. */
export const isSSXAlchemyProvider = (provider: SSXRPCProvider):
provider is SSXAlchemyProvider => provider.service === SSXRPCProviders.SSXAlchemyProvider;
-/** Cloudflare provider settings */
+/** Cloudflare provider settings. */
export type SSXCloudflareProvider = {
service: SSXRPCProviders.SSXCloudflareProvider;
};
-/* Type-Guard for SSXCloudflareProvider */
+/* Type-Guard for SSXCloudflareProvider. */
export const isSSXCloudflareProvider = (provider: SSXRPCProvider):
provider is SSXCloudflareProvider => provider.service === SSXRPCProviders.SSXCloudflareProvider;
-/** Enum of supported networks for Pocket */
+/** Enum of supported networks for Pocket. */
export enum SSXPocketProviderNetworks {
MAINNET = 'homestead',
ROPSTEN = 'ropsten',
@@ -141,47 +118,47 @@ export enum SSXPocketProviderNetworks {
GOERLI = 'goerli',
}
-/** Pocket provider settings */
+/** Pocket provider settings. */
export type SSXPocketProvider = {
service: SSXRPCProviders.SSXPocketProvider;
apiKey?: string;
network?: SSXPocketProviderNetworks;
};
-/* Type-Guard for SSXPocketProvider */
+/** Type-Guard for SSXPocketProvider. */
export const isSSXPocketProvider = (provider: SSXRPCProvider):
provider is SSXPocketProvider => provider.service === SSXRPCProviders.SSXPocketProvider;
-/** Enum of supported networks for Ankr */
+/** Enum of supported networks for Ankr. */
export enum SSXAnkrProviderNetworks {
MAINNET = 'homestead',
POLYGON = 'matic',
ARBITRUM = 'arbitrum',
}
-/** Ankr provider settings */
+/** Ankr provider settings. */
export type SSXAnkrProvider = {
service: SSXRPCProviders.SSXAnkrProvider;
apiKey?: string;
network?: SSXAnkrProviderNetworks;
};
-/* Type-Guard for SSXAnkrProvider */
+/** Type-Guard for SSXAnkrProvider. */
export const isSSXAnkrProvider = (provider: SSXRPCProvider):
provider is SSXAnkrProvider => provider.service === SSXRPCProviders.SSXAnkrProvider;
-/** Custom provider settings */
+/** Custom provider settings. */
export type SSXCustomProvider = {
service: SSXRPCProviders.SSXCustomProvider;
url?: string | ConnectionInfo;
network?: providers.Networkish;
};
-/* Type-Guard for SSXCustomProvider */
+/** Type-Guard for SSXCustomProvider. */
export const isSSXCustomProvider = (provider: SSXRPCProvider):
provider is SSXCustomProvider => provider.service === SSXRPCProviders.SSXCustomProvider;
-/** Generic provider settings */
+/** Generic provider settings. */
export type SSXGenericProvider = {
service: SSXRPCProviders;
url?: string | ConnectionInfo;
@@ -189,73 +166,6 @@ export type SSXGenericProvider = {
apiKey?: string | SSXInfuraProviderProjectSettings;
};
-/** SSX Session Store configuration settings */
-export interface SSXSessionStoreConfig {
- /** Overrides for [SessionOptions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a24d35afe48f7fb702e7617b983ddca1904ba36b/types/express-session/index.d.ts#L52) */
- sessionOptions?: Partial;
- /** Connector for different stores */
- store?: (session) => Store;
-}
-
-/** SSX Redis Session Store Provider settings */
-export type SSXRedisSessionStoreProvider = {
- service: 'redis';
- redisUrl: string;
-};
-
-/** SSX Express Session Store Provider settings */
-export type SSXExpressSessionStoreProvider = {
- service: 'express';
- // TODO(w4ll3): add app type and/or change config
- config?: SessionOptions;
-};
-
-/** SSX Metrics Provider settings */
-export type SSXMetricsProvider = {
- service: 'ssx';
- apiKey: string;
-};
-
-/** Configuration interface for cookies issued by ssx-server */
-export interface SSXCookieOptions extends CookieOptions {
- /** Prevents client-side javascript from accessing cookies. Should always be true. */
- httpOnly: true;
- /** Whether or not cookies should be sent over https. Recommend true for production. */
- secure: boolean;
- /** Prevents Cross Site Request Forgery Attacks by telling the browser to only send
- * cookies with request from your site. The lax setting allows GET requests from
- * other sites. Recommended true for production. */
- sameSite: boolean | 'lax' | 'strict' | 'none' | undefined;
- /** Whether or not cookies should be signed. Recommended true for production.
- * Set to true by providing a signing key. If false, cookies can be tampered
- * with on the client */
- signed: boolean;
-}
-
-/** Allowed fields for an SSX Log */
-export interface SSXLogFields {
- /** Unique identifier for the user, formatted as a DID */
- userId: string;
- /** RFC-3339 time of resource generation, defaults to now */
- timestamp?: string;
- /** Type of content being logged */
- type: SSXEventLogTypes;
- /** Any JSON stringifiable structure to be logged */
- content: string | Record;
-}
-
-/** Available SSX Log Types */
-export enum SSXEventLogTypes {
- /** Login type definition */
- LOGIN = 'ssx-login',
- /** Logout type definition */
- // LOGOUT = "ssx-logout",
- /** Logging type definition */
- // LOG = "LOG",
- /** Event type definition */
- // EVENT = "event",
-}
-
/** ENS options supported by SSX. */
export interface SSXEnsResolveOptions {
/** Enable ENS name/domain resolution. */
@@ -264,10 +174,10 @@ export interface SSXEnsResolveOptions {
avatar?: boolean;
}
-/** ENS data supported by SSX */
+/** ENS data supported by SSX. */
export interface SSXEnsData {
- /** ENS name/domain */
+ /** ENS name/domain. */
domain?: string | null,
- /** ENS avatar */
+ /** ENS avatar. */
avatarUrl?: string | null
}
\ No newline at end of file
diff --git a/packages/ssx-serverless/src/utils.ts b/packages/ssx-core/src/utils.ts
similarity index 54%
rename from packages/ssx-serverless/src/utils.ts
rename to packages/ssx-core/src/utils.ts
index 35d9d439..d24be161 100644
--- a/packages/ssx-serverless/src/utils.ts
+++ b/packages/ssx-core/src/utils.ts
@@ -8,6 +8,7 @@ import {
isSSXPocketProvider,
SSXAlchemyProviderNetworks,
SSXAnkrProviderNetworks,
+ SSXEnsData,
SSXEtherscanProviderNetworks,
SSXInfuraProviderNetworks,
SSXPocketProviderNetworks,
@@ -15,8 +16,9 @@ import {
} from './types';
import { ethers, getDefaultProvider } from 'ethers';
-/**
- * Returns an ethers provider based on the RPC configuration
+/**
+ * @param rpc - SSXRPCProvider
+ * @returns an ethers provider based on the RPC configuration.
*/
export const getProvider = (rpc?: SSXRPCProvider): ethers.providers.BaseProvider => {
if(!rpc) {
@@ -60,3 +62,53 @@ export const getProvider = (rpc?: SSXRPCProvider): ethers.providers.BaseProvider
}
return getDefaultProvider();
};
+
+/**
+ * Resolves ENS data supported by SSX.
+ * @param provider - Ether provider.
+ * @param address - User address.
+ * @param address - User address.
+ * @param resolveEnsOpts - Options to resolve ENS.
+ * @returns Object containing ENS data.
+ */
+ export const ssxResolveEns = async (
+ provider: ethers.providers.BaseProvider,
+ /* User Address */
+ address: string,
+ resolveEnsOpts: {
+ /* Enables ENS domain/name resolution */
+ domain?: boolean,
+ /* Enables ENS avatar resolution */
+ avatar?: boolean,
+ } = {
+ domain: true,
+ avatar: true
+ }
+ ): Promise => {
+ if (!address) {
+ throw new Error('Missing address.');
+ }
+ let ens: SSXEnsData = {};
+ let promises: Array> = [];
+ if (resolveEnsOpts?.domain) {
+ promises.push(provider.lookupAddress(address))
+ }
+ if (resolveEnsOpts?.avatar) {
+ promises.push(provider.getAvatar(address))
+ }
+
+ await Promise.all(promises)
+ .then(([domain, avatarUrl]) => {
+ if (!resolveEnsOpts.domain && resolveEnsOpts.avatar) {
+ [domain, avatarUrl] = [undefined, domain];
+ }
+ if (domain) {
+ ens['domain'] = domain;
+ }
+ if (avatarUrl) {
+ ens['avatarUrl'] = avatarUrl;
+ }
+ });
+
+ return ens;
+};
\ No newline at end of file
diff --git a/packages/ssx-core/tsconfig.json b/packages/ssx-core/tsconfig.json
new file mode 100644
index 00000000..506bc079
--- /dev/null
+++ b/packages/ssx-core/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
+ "compilerOptions": {
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
+ }
+}
diff --git a/packages/ssx-gnosis-extension/.eslintrc b/packages/ssx-gnosis-extension/.eslintrc
new file mode 100644
index 00000000..77983042
--- /dev/null
+++ b/packages/ssx-gnosis-extension/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "extends": [
+ "../../.eslintrc",
+ ],
+}
diff --git a/packages/ssx-gnosis-extension/.eslintrc.js b/packages/ssx-gnosis-extension/.eslintrc.js
deleted file mode 100644
index c2291ee6..00000000
--- a/packages/ssx-gnosis-extension/.eslintrc.js
+++ /dev/null
@@ -1,22 +0,0 @@
-module.exports = {
- env: {
- browser: true,
- es2021: true,
- },
- extends: [
- 'airbnb-base',
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended"
- ],
- parser: '@typescript-eslint/parser',
- parserOptions: {
- ecmaVersion: 'latest',
- sourceType: 'module',
- },
- plugins: [
- '@typescript-eslint',
- ],
- rules: {
- 'import/prefer-default-export': 'off',
- },
-};
diff --git a/packages/ssx-gnosis-extension/package.json b/packages/ssx-gnosis-extension/package.json
index 37c199e4..b449cfd9 100644
--- a/packages/ssx-gnosis-extension/package.json
+++ b/packages/ssx-gnosis-extension/package.json
@@ -15,6 +15,9 @@
"build": "tsc",
"clean": "rimraf dist"
},
+ "dependencies": {
+ "@spruceid/ssx-core": "*"
+ },
"peerDependencies": {
"siwe": "^2.1.2",
"ethers": "^5.7.1"
diff --git a/packages/ssx-gnosis-extension/src/gnosis.ts b/packages/ssx-gnosis-extension/src/gnosis.ts
index e7f8cf3a..2dbdb31b 100644
--- a/packages/ssx-gnosis-extension/src/gnosis.ts
+++ b/packages/ssx-gnosis-extension/src/gnosis.ts
@@ -9,17 +9,24 @@ import {
Contract, Event, providers, utils,
} from 'ethers';
+/** Contract Addresses by network. */
const CONTRACT_ADDRESS = {
mainnet: '0x469788fE6E9E9681C6ebF3bF78e7Fd26Fc015446',
rinkeby: '0x469788fE6E9E9681C6ebF3bF78e7Fd26Fc015446',
goerli: '0x469788fE6E9E9681C6ebF3bF78e7Fd26Fc015446',
};
+/** Contract definition for SetDelegate and ClearDelegate events. */
const CONTRACT_ABI = [
'event SetDelegate(address indexed delegator, bytes32 indexed id, address indexed delegate)',
'event ClearDelegate(address indexed delegator, bytes32 indexed id, address indexed delegate)',
];
+/**
+ * Gets network name based on chainId.
+ * @param chainId - chain identifier.
+ * @returns Network name.
+ */
const getNetworkName = (chainId: number): string => {
switch (chainId) {
case 1:
@@ -33,12 +40,24 @@ const getNetworkName = (chainId: number): string => {
}
};
+
+/**
+ * Gets contract address.
+ * @param provider - EthersJS provider.
+ * @returns Contract address.
+ */
const getContractAddress = async (
provider: providers.Provider,
): Promise => provider
.getNetwork()
.then(({ chainId }) => CONTRACT_ADDRESS[getNetworkName(chainId)]);
+/**
+ * Gets Gnosis delegation history events for an address.
+ * @param address - User address.
+ * @param provider - EthersJS provider.
+ * @returns List of delegation blocks.
+ */
export const getGnosisDelegationHistoryEventsFor = async (
address: string,
provider: providers.Provider,
@@ -70,6 +89,12 @@ export const getGnosisDelegationHistoryEventsFor = async (
]).then((e) => e.flat().sort((a, b) => a.blockNumber - b.blockNumber));
};
+/**
+ * Gets delegators for an address.
+ * @param address - User address.
+ * @param provider - EthersJS provider.
+ * @returns List of delegators for an address.
+ */
export const gnosisDelegatorsFor = async (
address: string,
provider: providers.Provider,
@@ -102,6 +127,13 @@ export const gnosisDelegatorsFor = async (
);
};
+/**
+ * Verifies if address if delegate of delegator.
+ * @param delegateAddress - Delegate address.
+ * @param delegator - Delegator address.
+ * @param provider - EthersJS provider.
+ * @returns True (if is delegate) or false (on the contrary).
+ */
export const addressIsDelegateOf = async (
delegateAddress: string,
delegator: string,
@@ -111,6 +143,14 @@ export const addressIsDelegateOf = async (
return delegators.includes(delegator);
};
+/**
+ * Giving a message, verifies if the address is a delegee.
+ * @param params - Verify params.
+ * @param opts - Verify Options.
+ * @param message - SIWE Message.
+ * @param _
+ * @returns JSON with information about the delegations.
+ */
export const SiweGnosisVerify = async (
params: VerifyParams,
opts: VerifyOpts,
diff --git a/packages/ssx-gnosis-extension/src/modal.ts b/packages/ssx-gnosis-extension/src/modal.ts
index f7af8e0c..c062c39a 100644
--- a/packages/ssx-gnosis-extension/src/modal.ts
+++ b/packages/ssx-gnosis-extension/src/modal.ts
@@ -1,18 +1,30 @@
+import { ConfigOverrides, ISSXConnected, SSXExtension } from '@spruceid/ssx-core';
import { providers } from 'ethers';
import { gnosisDelegatorsFor } from './gnosis';
declare global {
interface Window { gnosisModal: IGnosisModal; }
}
+
+/** Gnosis Modal Interface */
interface IGnosisModal {
+ /** Method to close the modal. */
closeModal: () => void;
+ /** Method to open modal. */
openModal: () => Promise;
+ /** Method to select delegation option on modal. */
selectOption: (opt: any) => void;
+ /** Method to connect with selected option. */
connect: () => Promise;
}
const styles = '.ssx-gnosis-ssx-gnosis-modal--body{font-family:Satoshi;margin:0;background-color:#000}.ssx-gnosis-modal--container{display:flex;justify-content:center;align-items:center;position:fixed;width:100%;height:100%;top:0;visibility:hidden;opacity:0;transition:all 0.3s ease}.ssx-gnosis-modal--container .ssx-gnosis-modal--backdrop{background:rgba(15,15,24,.6);position:fixed;width:100%;height:100%}.ssx-gnosis-modal--container.visible{opacity:1;visibility:visible}.ssx-gnosis-modal--container .ssx-gnosis-modal--content{max-width:100%;width:500px;position:fixed;top:calc((100vh - 550px - 120px)/2);transition:all 0.8s ease;z-index:9999}.ssx-gnosis-modal--header,.ssx-gnosis-modal--subheader,.ssx-gnosis-modal--footer{padding:1rem}.ssx-gnosis-modal--body{height:300px;overflow-y:auto}.ssx-gnosis-modal--body .ssx-gnosis-modal--option{font-size:16px;font-weight:400;padding:15px 30px;cursor:pointer}.ssx-gnosis-modal--body .ssx-gnosis-modal--info{width:100%;height:100%;display:flex;flex-wrap:wrap;text-align:center;justify-content:center;align-items:center}.ssx-gnosis-modal--body .ssx-gnosis-modal--info p{font-size:26px;font-weight:700;line-height:30px;margin-top:22px;margin-bottom:22px}.ssx-gnosis-modal--body .ssx-gnosis-modal--info a{-webkit-appearance:button;-moz-appearance:button;appearance:button;text-decoration:none;cursor:pointer;border-radius:100px;width:174px;height:45px;font-size:16px;font-weight:700;line-height:25px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;margin:auto}.ssx-gnosis-modal--body .ssx-gnosis-modal--info a img{margin-right:12px}.ssx-gnosis-modal--body .ssx-gnosis-modal--loader{width:100%;height:100%;display:flex;flex-wrap:wrap;justify-content:center;align-items:center}.ssx-gnosis-modal--body .ssx-gnosis-modal--loader img{width:100px;height:100px}.ssx-gnosis-modal--header{display:flex;justify-content:space-between;align-items:center}.ssx-gnosis-modal--header .ssx-gnosis-modal--brand{display:flex;flex-wrap:wrap;align-items:center;justify-content:center}.ssx-gnosis-modal--header h1{margin-left:12px;font-size:30px;line-height:46px;font-weight:900}.ssx-gnosis-modal--header button{font-size:20px;padding:12px;margin:0;height:40px;width:40px;border-radius:100px;border-style:none;cursor:pointer}.ssx-gnosis-modal--subheader{border-top-left-radius:20px;border-top-right-radius:20px;text-align:right}.ssx-gnosis-modal--subheader .ssx-gnosis-modal--results-counter{font-size:16px;font-weight:400;line-height:25.5px}.ssx-gnosis-modal--footer{text-align:right;border-bottom-left-radius:20px;border-bottom-right-radius:20px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap}.ssx-gnosis-modal--btn{display:inline-block;border:0;cursor:pointer;font-size:16px;line-height:24.5px;font-weight:700;padding:11px 25px}.ssx-gnosis-modal--btn.disabled{cursor:not-allowed;opacity:.4}.ssx-gnosis-modal-rotating{animation:ssx-gnosis-modal-rotating 0.7s linear infinite;-o-animation:ssx-gnosis-modal-rotating 0.7s linear infinite;-ms-animation:ssx-gnosis-modal-rotating 0.7s linear infinite;-moz-animation:ssx-gnosis-modal-rotating 0.7s linear infinite;-webkit-animation:ssx-gnosis-modal-rotating 0.7s linear infinite}@keyframes ssx-gnosis-modal-rotating{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(360deg)}}.ssx-gnosis-modal--theme-dark{color:#fff}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--header button{background:#fff;color:#000}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--subheader,.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body{background-color:#293137}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--info a{background-color:#fff;color:#24262A}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--info a img{filter:brightness(0) saturate(100%) invert(30%) sepia(96%) saturate(1424%) hue-rotate(147deg) brightness(90%) contrast(101%)}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--loader img{filter:invert(1)}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body::-webkit-scrollbar-track{border-radius:20px;background-color:#3F464B}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body::-webkit-scrollbar-thumb{border-radius:8px;background-color:#898f94}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body::-webkit-scrollbar{background-color:#898f94;border-radius:20px;height:6px;width:6px}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--option{background-color:transparent;border-bottom:1px solid #3F464B}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--option.selected{background-color:#24262A}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--body .ssx-gnosis-modal--option:hover{background-color:#24262A}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--footer{background-color:#3F464B}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--subheader{border-bottom:1px solid #3F464B}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--footer{border-top:1px solid #3F464B}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--btn.secondary{background:transparent;color:#ccc}.ssx-gnosis-modal--theme-dark .ssx-gnosis-modal--btn.primary{border-radius:8px;background:#656B6F;color:#fff}';
+
+/**
+ * Gets modal loader component.
+ * @returns Modal Loader HTML element.
+ */
const getModalLoader = (): Element => {
const loader = document.createElement("div");
loader.classList.add("ssx-gnosis-modal--loader");
@@ -41,6 +53,10 @@ const getModalLoader = (): Element => {
return loader;
}
+/**
+ * Gets error component.
+ * @returns Modal Error HTML element.
+ */
const getErrorModal = (): Element => {
const info = document.createElement('div');
info.classList.add('ssx-gnosis-modal--info');
@@ -108,6 +124,10 @@ const getErrorModal = (): Element => {
return info;
}
+/**
+ * Gets base modal component.
+ * @returns Base Modal HTML element.
+ */
const getBaseModal = (): Element => {
const container = document.createElement("div");
container.classList.add("ssx-gnosis-modal--container", "ssx-gnosis-modal--theme-dark");
@@ -204,17 +224,29 @@ const getBaseModal = (): Element => {
return container;
}
-
-export class GnosisDelegation {
+/**
+ * GnosisDelegation is an SSX Extension to enable multisig login on SSX.
+ */
+export class GnosisDelegation implements SSXExtension {
+ /** Web3 Provider. */
public web3provider: providers.Web3Provider;
+ /** Selected delegation option. */
public selectedOption: string = '';
- private _proceed: (value: any | PromiseLike) => void;
+ /** Continue with the SSX flow with a successfull promise. */
+ private _proceed: (value: ConfigOverrides | PromiseLike) => void;
+ /** Continue with the SSX flow with a rejected promise. */
private _failure: (reason?: any) => void;
+ /** User address without delegation. */
private _connectedAddress: string;
namespace = "delegationRegistry";
- async afterConnect(ssx: any): Promise {
+ /**
+ * Executes extension logic.
+ * @param ssx - SSXConnected instance.
+ * @returns Promise with extension status.
+ */
+ async afterConnect(ssx: ISSXConnected): Promise {
this.web3provider = ssx.provider;
this._connectedAddress = await ssx.provider.getSigner().getAddress();
@@ -226,14 +258,17 @@ export class GnosisDelegation {
};
window.gnosisModal = gnosisModal;
- return new Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
this.openModal();
this._proceed = resolve;
this._failure = reject;
});
}
- openModal = async () => {
+ /**
+ * Opens GnosisModal.
+ */
+ openModal = async (): Promise => {
this.selectedOption = '';
const {
modal, modalBody, modalCounter, continueBtn,
@@ -284,6 +319,11 @@ export class GnosisDelegation {
});
};
+
+ /**
+ * Gets static HTML tags to build the main component.
+ * @returns JSON with static HTML tags.
+ */
getTags = (): Record => {
// append modal to the body
const modalWrapper = document.createElement('div');
@@ -311,22 +351,37 @@ export class GnosisDelegation {
};
};
+ /**
+ * Gets delegators.
+ * @returns List of delegators.
+ */
getOptions = async (): Promise> => gnosisDelegatorsFor(
this._connectedAddress,
this.web3provider,
);
- selectOption = (option) => {
+ /**
+ * Selects delegation option.
+ * @param option - Modal option.
+ */
+ selectOption = (option): void => {
document.getElementById(`ssx-gnosis-modal--option-${this.selectedOption}`).classList.remove('selected');
document.getElementById('ssx-gnosis-modal--continue-btn').classList.remove('disabled');
this.selectedOption = option;
document.getElementById(`ssx-gnosis-modal--option-${option}`).classList.add('selected');
};
- closeModal = () => {
+ /**
+ * Closes Modal.
+ */
+ closeModal = (): void => {
document.getElementById('ssx-gnosis-modal--wrapper').remove();
};
+ /**
+ * Confirm selection and continue SSX flow.
+ * @returns Promise void.
+ */
connect = async (): Promise => {
if (!this.selectedOption.replace(/Yourself - /, '')) {
this._failure(new Error("Invalid address selected."));
diff --git a/packages/ssx-gnosis-extension/tsconfig.json b/packages/ssx-gnosis-extension/tsconfig.json
index e0a0c4d9..506bc079 100644
--- a/packages/ssx-gnosis-extension/tsconfig.json
+++ b/packages/ssx-gnosis-extension/tsconfig.json
@@ -1,103 +1,13 @@
{
- "exclude": ["dist/", "node_modules"],
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- "lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- // "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
}
}
diff --git a/packages/ssx-react/src/ssx.tsx b/packages/ssx-react/src/ssx.tsx
index 81ead924..1ddcd5ac 100644
--- a/packages/ssx-react/src/ssx.tsx
+++ b/packages/ssx-react/src/ssx.tsx
@@ -1,24 +1,24 @@
import { useContext, createContext, useState, useEffect, ReactNode } from 'react';
-import { SSX, SSXConfig } from "@spruceid/ssx";
+import { SSX, SSXClientConfig } from "@spruceid/ssx";
import { useSigner } from 'wagmi';
-/** Props for SSX Provider */
+/** Props for SSX Provider. */
export interface SSXProviderProps {
- /** Optional SSX configuration, used for instantiating an SSX Instance */
- ssxConfig?: SSXConfig;
- /** Provider child nodes, for rendering*/
+ /** Optional SSX configuration, used for instantiating an SSX Instance. */
+ ssxConfig?: SSXClientConfig;
+ /** Provider child nodes, for rendering. */
children: ReactNode;
}
-/** Interface for contents provided to the Hook */
+/** Interface for contents provided to the Hook. */
export interface SSXContextInterface {
- /** SSX Instance */
+ /** SSX Instance. */
ssx: SSX | undefined;
- /** SSX Instance loading state */
+ /** SSX Instance loading state. */
ssxLoaded: boolean;
}
-/** Default, uninitialized context */
+/** Default, uninitialized context. */
const defaultContext: SSXContextInterface = {
ssx: undefined,
ssxLoaded: false,
@@ -26,7 +26,7 @@ const defaultContext: SSXContextInterface = {
const SSXContext = createContext(defaultContext);
-/** SSX Provider Component */
+/** SSX Provider Component. */
export const SSXProvider = ({ ssxConfig, children }: SSXProviderProps) => {
const { data: signer, isSuccess: signerLoaded } = (typeof window !== 'undefined' && useSigner()) || { data: undefined, isSuccess: false };
const [ssx, setSSX] = useState();
@@ -66,7 +66,7 @@ export const SSXProvider = ({ ssxConfig, children }: SSXProviderProps) => {
);
}
-/** Hook for accessing SSX instance and state */
+/** Hook for accessing SSX instance and state. */
export const useSSX = (): SSXContextInterface => {
return useContext(SSXContext);
};
\ No newline at end of file
diff --git a/packages/ssx-react/tsconfig.json b/packages/ssx-react/tsconfig.json
index efee40a1..506bc079 100644
--- a/packages/ssx-react/tsconfig.json
+++ b/packages/ssx-react/tsconfig.json
@@ -1,102 +1,13 @@
{
- "include": ["src/**/*"],
- "exclude": ["node_modules/", "dist/**/*"],
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Enable incremental compilation */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- "lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
- // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "resolveJsonModule": true, /* Enable importing .json files */
- // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- // "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
- // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
- // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
}
}
diff --git a/packages/ssx-sdk/.eslintrc b/packages/ssx-sdk/.eslintrc
new file mode 100644
index 00000000..77983042
--- /dev/null
+++ b/packages/ssx-sdk/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "extends": [
+ "../../.eslintrc",
+ ],
+}
diff --git a/packages/ssx-sdk/.eslintrc.js b/packages/ssx-sdk/.eslintrc.js
deleted file mode 100644
index 771e9246..00000000
--- a/packages/ssx-sdk/.eslintrc.js
+++ /dev/null
@@ -1,30 +0,0 @@
-module.exports = {
- env: {
- browser: true,
- es2021: true,
- },
- extends: [
- 'airbnb-base',
- ],
- parser: '@typescript-eslint/parser',
- parserOptions: {
- ecmaVersion: 'latest',
- sourceType: 'module',
- },
- plugins: [
- '@typescript-eslint',
- ],
- rules: {
- 'object-property-newline': 'error',
- 'import/prefer-default-export': 'off',
- 'no-promise-executor-return': 'warn',
- 'no-unused-vars': ['warn', { vars: 'all', args: 'after-used', ignoreRestSiblings: false }],
- 'no-use-before-define': 'warn',
- 'import/extensions': 'off',
- 'import/no-unresolved': 'off',
- 'max-len': 'warn',
- 'max-classes-per-file': 'off',
- 'no-plusplus': 'off',
- 'no-await-in-loop': 'off',
- },
-};
diff --git a/packages/ssx-sdk/api-extractor.json b/packages/ssx-sdk/api-extractor.json
index 83ecb020..0fd4df20 100644
--- a/packages/ssx-sdk/api-extractor.json
+++ b/packages/ssx-sdk/api-extractor.json
@@ -60,7 +60,7 @@
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
* local files for library1.
*/
- "bundledPackages": ["@spruceid/siwe", "@spruceid/ssx-wasm"],
+ "bundledPackages": ["@spruceid/ssx-core", "@spruceid/ssx-sdk-wasm"],
/**
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
diff --git a/packages/ssx-sdk/package.json b/packages/ssx-sdk/package.json
index 4160c694..b709fb84 100644
--- a/packages/ssx-sdk/package.json
+++ b/packages/ssx-sdk/package.json
@@ -27,6 +27,7 @@
"dependencies": {
"@metamask/detect-provider": "^1.2.0",
"siwe": "^2.1.2",
+ "@spruceid/ssx-core": "*",
"@spruceid/ssx-gnosis-extension": "*",
"@spruceid/ssx-sdk-wasm": "0.1.2",
"@types/lodash.merge": "^4.6.7",
diff --git a/packages/ssx-sdk/src/core.ts b/packages/ssx-sdk/src/core.ts
index a798baec..3d4fe1ea 100644
--- a/packages/ssx-sdk/src/core.ts
+++ b/packages/ssx-sdk/src/core.ts
@@ -6,53 +6,58 @@ import {
import merge from 'lodash.merge';
import axios, { AxiosInstance } from 'axios';
import { generateNonce } from 'siwe';
-import { SSXExtension } from './extension';
import {
- SSXSession,
- SSXConfig,
+ SSXClientSession,
+ SSXClientConfig,
SSXEnsResolveOptions,
-} from './types';
+ ISSXConnected,
+ SSXExtension
+} from '@spruceid/ssx-core';
-/** Initializer for an SSXSession. */
+/** Initializer for an SSXClientSession. */
export class SSXInit {
- /** Extensions for the SSXSession. */
+ /** Extensions for the SSXClientSession. */
private extensions: SSXExtension[] = [];
- constructor(private config?: SSXConfig) { }
+ constructor(private config?: SSXClientConfig) { }
/** Extend the session with an SSX compatible extension. */
extend(extension: SSXExtension) {
this.extensions.push(extension);
}
- /** Connect to the signing account using the configured provider. */
+ /**
+ * Connect to the signing account using the configured provider.
+ * @returns SSXConnected instance.
+ */
async connect(): Promise {
// TODO(w4ll3): consider creating a custom error object, i.e: SSXConnectError
let provider: ethers.providers.Web3Provider;
- try {
- // eslint-disable-next-line no-underscore-dangle
- if (!this.config.providers.web3.driver?._isProvider) {
- provider = new ethers.providers.Web3Provider(this.config.providers.web3.driver);
- } else {
- provider = this.config.providers.web3.driver;
- }
+ // eslint-disable-next-line no-underscore-dangle
+ if (!this.config.providers.web3.driver?._isProvider) {
try {
- if (!this.config.providers.web3?.driver?.bridge?.includes('walletconnect')) {
- const connectedAccounts = await provider.listAccounts();
- if (connectedAccounts.length === 0) {
- await provider.send('wallet_requestPermissions', [{ eth_accounts: {} }]);
- }
- }
+ provider = new ethers.providers.Web3Provider(this.config.providers.web3.driver);
} catch (err) {
- // Permission rejected error
+ // Provider creation error
console.error(err);
throw err;
}
- } catch (err) {
- // Provider creation error
- console.error(err);
- throw err;
+ } else {
+ provider = this.config.providers.web3.driver;
+ }
+
+ if (!this.config.providers.web3?.driver?.bridge?.includes('walletconnect')) {
+ const connectedAccounts = await provider.listAccounts();
+ if (connectedAccounts.length === 0) {
+ try {
+ await provider.send('wallet_requestPermissions', [{ eth_accounts: {} }]);
+ } catch (err) {
+ // Permission rejected error
+ console.error(err);
+ throw err;
+ }
+ }
}
let builder;
@@ -70,20 +75,27 @@ export class SSXInit {
}
/** An intermediate SSX state: connected, but not signed-in. */
-export class SSXConnected {
- /** Promise that is initialized on construction of this class to run the "afterConnect" methods
+export class SSXConnected implements ISSXConnected {
+ /**
+ * Promise that is initialized on construction of this class to run the "afterConnect" methods
* of the extensions.
*/
public afterConnectHooksPromise: Promise;
+ /** Verifies if extension is enabled. */
public isExtensionEnabled = (namespace: string) => this.extensions.filter((e) => e.namespace === namespace).length === 1;
+ /** Axios instance. */
public api?: AxiosInstance;
constructor(
+ /** Instance of SSXSessionBuilder */
public builder: ssxSession.SSXSessionBuilder,
- public config: SSXConfig,
+ /** SSXConfig object. */
+ public config: SSXClientConfig,
+ /** Enabled extensions. */
public extensions: SSXExtension[],
+ /** EthersJS provider. */
public provider: ethers.providers.Web3Provider,
) {
this.afterConnectHooksPromise = this.applyExtensions();
@@ -96,7 +108,6 @@ export class SSXConnected {
}
/** Applies the "afterConnect" methods and the delegated capabilities of the extensions. */
-
public async applyExtensions(): Promise {
for (const extension of this.extensions) {
if (extension.afterConnect) {
@@ -127,8 +138,11 @@ export class SSXConnected {
}
}
- /** Applies the "afterSignIn" methods of the extensions. */
- public async afterSignIn(session: SSXSession): Promise {
+ /**
+ * Applies the "afterSignIn" methods of the extensions.
+ * @param session - SSXClientSession object.
+ */
+ public async afterSignIn(session: SSXClientSession): Promise {
for (const extension of this.extensions) {
if (extension.afterSignIn) {
await extension.afterSignIn(session);
@@ -136,30 +150,39 @@ export class SSXConnected {
}
}
+ /**
+ * Requests nonce from server.
+ * @param params - Request params.
+ * @returns Promise with nonce.
+ */
public async ssxServerNonce(params: Record): Promise {
- try {
- if (this.api) {
- const { data: nonce } = await this.api.get('/ssx-nonce', { params });
- if (!nonce) {
- throw new Error('Unable to retrieve nonce from server.');
- }
- return nonce;
+ if (this.api) {
+ let nonce;
+ try {
+ nonce = (await this.api.get('/ssx-nonce', { params })).data;
+ } catch (error) {
+ console.error(error);
+ throw error;
}
- } catch (error) {
- // were do we log this error? ssx.log?
- // show to user?
- console.error(error);
- throw error;
+ if (!nonce) {
+ throw new Error('Unable to retrieve nonce from server.');
+ }
+ return nonce;
}
}
- public async ssxServerLogin(session: SSXSession): Promise {
- try {
- if (this.api) {
- let resolveEns: boolean | SSXEnsResolveOptions = false;
- if (typeof this.config.resolveEns === 'object' && this.config.resolveEns.resolveOnServer) {
- resolveEns = this.config.resolveEns.resolve;
- }
+ /**
+ * Requests sign in from server and returns session.
+ * @param session - SSXClientSession object.
+ * @returns Promise with server session data.
+ */
+ public async ssxServerLogin(session: SSXClientSession): Promise {
+ if (this.api) {
+ let resolveEns: boolean | SSXEnsResolveOptions = false;
+ if (typeof this.config.resolveEns === 'object' && this.config.resolveEns.resolveOnServer) {
+ resolveEns = this.config.resolveEns.resolve;
+ }
+ try {
// @TODO(w4ll3): figure out how to send a custom sessionKey
return this.api.post('/ssx-login', {
signature: session.signature,
@@ -171,22 +194,21 @@ export class SSXConnected {
resolveEns
})
.then((response) => response.data);
+ } catch (error) {
+ console.error(error);
+ throw error;
}
- } catch (error) {
- // were do we log this error? ssx.log?
- // show to user?
- console.error(error);
- throw error;
}
}
- /** Requests the user to sign in.
- *
- * Generates the SIWE message for this session, requests the configured
- * Signer to sign the message, calls the "afterSignIn" methods of the
- * extensions and returns the SSXSession object.
- */
- async signIn(): Promise {
+ /**
+ * Requests the user to sign in.
+ * Generates the SIWE message for this session, requests the configured
+ * Signer to sign the message, calls the "afterSignIn" methods of the
+ * extensions.
+ * @returns Promise with the SSXClientSession object.
+ */
+ async signIn(): Promise {
await this.afterConnectHooksPromise;
const sessionKey = this.builder.jwk();
@@ -232,16 +254,18 @@ export class SSXConnected {
return session;
}
- async signOut(session: SSXSession): Promise {
- try {
- if (this.api) {
+ /**
+ * Requests the user to sign out.
+ * @param session - SSXClientSession object.
+ */
+ async signOut(session: SSXClientSession): Promise {
+ if (this.api) {
+ try {
await this.api.post('/ssx-logout', { ...session });
+ } catch (error) {
+ console.error(error);
+ throw error;
}
- } catch (error) {
- // were do we log this error? ssx.log?
- // show to user?
- console.error(error);
- throw error;
}
}
}
diff --git a/packages/ssx-sdk/src/extension.ts b/packages/ssx-sdk/src/extension.ts
deleted file mode 100644
index 45953565..00000000
--- a/packages/ssx-sdk/src/extension.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { ssxSession } from '@spruceid/ssx-sdk-wasm';
-import { SSXConnected } from './core';
-import { SSXSession, SiweConfig } from './types';
-
-/** Interface for an extension to SSX. */
-export interface SSXExtension {
- /** [recap] Capability namespace. */
- namespace?: string,
- /** [recap] Default delegated actions in capability namespace. */
- defaultActions?(): Promise,
- /** [recap] Delegated actions by target in capability namespace. */
- targetedActions?(): Promise<{ [target: string]: string[] }>,
- /** [recap] Extra metadata to help validate the capability. */
- extraFields?(): Promise,
- /** Hook to run after SSX has connected to the user's wallet.
- * This can return an object literal to override the session configuration before the user
- * signs in. */
- afterConnect?(ssx: SSXConnected): Promise;
- /** Hook to run after SSX has signed in. */
- afterSignIn?(session: SSXSession): Promise,
-}
-
-export type ExtraFields = ssxSession.ExtraFields;
-
-/** Overrides for the session configuration. */
-export type ConfigOverrides = {
- siwe?: SiweConfig
-};
diff --git a/packages/ssx-sdk/src/index.ts b/packages/ssx-sdk/src/index.ts
index e1fa61a3..445bfc77 100644
--- a/packages/ssx-sdk/src/index.ts
+++ b/packages/ssx-sdk/src/index.ts
@@ -1,4 +1,12 @@
export * from './ssx';
-export * from './extension';
export * from './core';
-export * from './types';
+export * from '@spruceid/ssx-core/dist/client/types';
+export * from '@spruceid/ssx-core/dist/types';
+export {
+ /** @deprecated use SSXClientConfig field instead */
+ SSXClientConfig as SSXConfig,
+ /** @deprecated use SSXClientProviders field instead */
+ SSXClientProviders as SSXProviders,
+ /** @deprecated use SSXClientSession field instead */
+ SSXClientSession as SSXSession,
+} from '@spruceid/ssx-core';
\ No newline at end of file
diff --git a/packages/ssx-sdk/src/ssx.ts b/packages/ssx-sdk/src/ssx.ts
index 88f6e3f9..42005597 100644
--- a/packages/ssx-sdk/src/ssx.ts
+++ b/packages/ssx-sdk/src/ssx.ts
@@ -4,12 +4,12 @@ import {
SSXInit,
} from './core';
import {
- SSXConfig,
- SSXSession,
+ SSXClientConfig,
+ SSXClientSession,
SSXRPCProviders,
SSXEnsData,
SSXEnsResolveOptions,
-} from './types';
+} from '@spruceid/ssx-core';
declare global {
interface Window {
@@ -17,7 +17,7 @@ declare global {
}
}
-const SSX_DEFAULT_CONFIG: SSXConfig = {
+const SSX_DEFAULT_CONFIG: SSXClientConfig = {
providers: {
web3: {
driver: globalThis.ethereum,
@@ -30,11 +30,11 @@ const SSX_DEFAULT_CONFIG: SSXConfig = {
* A toolbox for user-controlled identity, credentials, storage and more.
*/
export class SSX {
- /** SSXSession builder. */
+ /** SSXClientSession builder. */
private init: SSXInit;
/** The session representation (once signed in). */
- public session?: SSXSession;
+ public session?: SSXClientSession;
/** Current connection of SSX */
public connection?: SSXConnected;
@@ -42,7 +42,7 @@ export class SSX {
/** Supported RPC Providers */
public static RPCProviders = SSXRPCProviders;
- constructor(private config: SSXConfig = SSX_DEFAULT_CONFIG) {
+ constructor(private config: SSXClientConfig = SSX_DEFAULT_CONFIG) {
this.init = new SSXInit({ ...this.config, providers: { ...SSX_DEFAULT_CONFIG.providers, ...this.config?.providers } });
if (this.config.enableDaoLogin) {
@@ -55,7 +55,7 @@ export class SSX {
* Request the user to sign in, and start the session.
* @returns Object containing information about the session
*/
- async signIn(): Promise {
+ async signIn(): Promise {
try {
this.connection = await this.init.connect();
} catch (err) {
@@ -66,19 +66,19 @@ export class SSX {
try {
this.session = await this.connection.signIn();
- if (this.config.resolveEns) {
- if (this.config.resolveEns === true) {
- this.session.ens = await this.resolveEns(this.session.address);
- } else if (!this.config.resolveEns.resolveOnServer) {
- this.session.ens = await this.resolveEns(this.session.address, this.config.resolveEns.resolve);
- }
- }
- return this.session;
} catch (err) {
// Request to /ssx-login went wrong
console.error(err);
throw err;
}
+ if (this.config.resolveEns) {
+ if (this.config.resolveEns === true) {
+ this.session.ens = await this.resolveEns(this.session.address);
+ } else if (!this.config.resolveEns.resolveOnServer) {
+ this.session.ens = await this.resolveEns(this.session.address, this.config.resolveEns.resolve);
+ }
+ }
+ return this.session;
}
/**
@@ -91,9 +91,9 @@ export class SSX {
/** User address */
address: string,
resolveEnsOpts: SSXEnsResolveOptions = {
- domain: true,
- avatar: true
- }
+ domain: true,
+ avatar: true
+ }
): Promise {
if (!address) {
throw new Error('Missing address.');
@@ -126,21 +126,27 @@ export class SSX {
/**
* Invalidates user's session.
*/
- async signOut() {
+ async signOut(): Promise {
try {
await this.connection.signOut(this.session);
- this.session = null;
- this.connection = null;
} catch (err) {
// request to /ssx-logout went wrong
console.error(err);
throw err;
}
+ this.session = null;
+ this.connection = null;
}
- /** Get the address that is connected and signed in. */
+ /**
+ * Gets the address that is connected and signed in.
+ * @returns Address.
+ */
address: () => string | undefined = () => this.session?.address;
- /** Get the chainId that the address is connected and signed in on. */
+ /**
+ * Get the chainId that the address is connected and signed in on.
+ * @returns chainId.
+ */
chainId: () => number | undefined = () => this.session?.chainId;
}
diff --git a/packages/ssx-sdk/src/types.ts b/packages/ssx-sdk/src/types.ts
deleted file mode 100644
index 11b7cbfa..00000000
--- a/packages/ssx-sdk/src/types.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-/* eslint-disable no-shadow */
-import { ssxSession } from '@spruceid/ssx-sdk-wasm';
-import { providers } from 'ethers';
-import { ConnectionInfo } from 'ethers/lib/utils';
-
-/** Supported storage types. */
-export enum StorageType {
-}
-
-/** Core config for SSX. */
-export interface SSXConfig {
- /** Whether or not daoLogin is enabled. */
- enableDaoLogin?: boolean;
- /** Connection to a cryptographic keypair and/or network. */
- providers?: SSXProviders;
- /** Optional session configuration for the SIWE message. */
- siweConfig?: SiweConfig;
- storage?: StorageModule;
- /** Whether or not ENS resolution is enabled. True means resolve all on client. */
- resolveEns?: boolean | SSXEnsConfig;
-}
-
-/** Selection and configuration of the storage module. */
-export enum StorageModule {
-}
-
-/** Representation of an active SSXSession. */
-export type SSXSession = {
- address: string;
- walletAddress: string;
- chainId: number;
- sessionKey: string;
- siwe: string;
- signature: string;
- ens?: SSXEnsData;
-};
-
-/** The URL of the server running ssx-server. Providing this field enables SIWE server communication */
-export type ServerHost = string;
-
-/** The ssx-powered server configuration settings */
-export type SSXProviderServer = {
- host: ServerHost;
-};
-
-/** Web3 provider configuration settings */
-export interface SSXProviderWeb3 {
- /**
- * window.ethereum for Metamask;
- * web3modal.connect() for Web3Modal;
- * const signer = useSigner(); const provider = signer.provider; from Wagmi for Rainbowkit
- * */
- driver: any;
-}
-
-/** SSX web3 configuration settings */
-export interface SSXProviders {
- /** Web3 wallet provider */
- web3?: SSXProviderWeb3;
- /** JSON RPC provider configurations */
- rpc?: SSXRPCProvider;
- /** Optional reference to server running ssx-server.
- * Providing this field enables communication with ssx-server
- */
- server?: SSXProviderServer;
-}
-
-export type SSXRPCProvider = SSXEtherscanProvider | SSXInfuraProvider | SSXAlchemyProvider | SSXCloudflareProvider | SSXPocketProvider | SSXAnkrProvider | SSXCustomProvider;
-
-/** Enum of supported RPC providers */
-export enum SSXRPCProviders {
- SSXEtherscanProvider = 'etherscan',
- SSXInfuraProvider = 'infura',
- SSXAlchemyProvider = 'alchemy',
- SSXCloudflareProvider = 'cloudflare',
- SSXPocketProvider = 'pocket',
- SSXAnkrProvider = 'ankr',
- SSXCustomProvider = 'custom',
-}
-
-/** Enum of supported networks for Etherscan */
-export enum SSXEtherscanProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
-}
-
-/** Etherscan provider settings */
-export type SSXEtherscanProvider = {
- service: SSXRPCProviders.SSXEtherscanProvider;
- apiKey?: string | number;
- network?: SSXEtherscanProviderNetworks;
-};
-
-/** Enum of supported networks for Infura */
-export enum SSXInfuraProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
- POLYGON = 'matic',
- POLYGON_MUMBAI = 'maticmum',
- OPTIMISM = 'optimism',
- OPTIMISM_KOVAN = 'optimism-kovan',
- ARBITRUM = 'arbitrum',
- ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
-}
-
-/** Infura provider project settings */
-export type SSXInfuraProviderProjectSettings = {
- projectId: string;
- projectSecret: string;
-};
-
-/** Infura provider settings */
-export type SSXInfuraProvider = {
- service: SSXRPCProviders.SSXInfuraProvider;
- apiKey: string | SSXInfuraProviderProjectSettings;
- network?: SSXInfuraProviderNetworks;
-};
-
-/** Enum of supported networks for Alchemy */
-export enum SSXAlchemyProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
- POLYGON = 'matic',
- POLYGON_MUMBAI = 'maticmum',
- OPTIMISM = 'optimism',
- OPTIMISM_KOVAN = 'optimism-kovan',
- ARBITRUM = 'arbitrum',
- ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
-}
-
-/** Alchemy provider settings */
-export type SSXAlchemyProvider = {
- service: SSXRPCProviders.SSXAlchemyProvider;
- apiKey?: string | number;
- network?: SSXAlchemyProviderNetworks;
-};
-
-/** Cloudflare provider settings */
-export type SSXCloudflareProvider = {
- service: SSXRPCProviders.SSXCloudflareProvider;
-};
-
-/** Enum of supported networks for Pocket */
-export enum SSXPocketProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
-}
-
-/** Pocket provider settings */
-export type SSXPocketProvider = {
- service: SSXRPCProviders.SSXPocketProvider;
- apiKey?: string | number;
- network?: SSXPocketProviderNetworks;
-};
-
-/** Enum of supported networks for Ankr */
-export enum SSXAnkrProviderNetworks {
- MAINNET = 'homestead',
- POLYGON = 'matic',
- ARBITRUM = 'arbitrum',
-}
-
-/** Ankr provider settings */
-export type SSXAnkrProvider = {
- service: SSXRPCProviders.SSXAnkrProvider;
- apiKey?: string | number;
- network?: SSXAnkrProviderNetworks;
-};
-
-/** Custom provider settings */
-export type SSXCustomProvider = {
- service: SSXRPCProviders.SSXCustomProvider;
- url?: string | ConnectionInfo;
- network?: providers.Networkish;
-};
-
-/** Optional session configuration for the SIWE message. */
-export interface SiweConfig extends Partial { }
-
-/** A Storage module. */
-export interface Storage {
- /** Retrieve a value from storage. */
- get(key: string): Promise,
- /** Insert a key-value pair into storage. */
- put(key: string, value: any): Promise,
- /** List the stored values by key, optionally filtered by prefix. */
- list(prefix?: string): Promise,
- /** Delete a value from storage. */
- delete(key: string): Promise,
-}
-
-/** ENS data supported by SSX. */
-export interface SSXEnsData {
- /** ENS name/domain. */
- domain?: string | null,
- /** ENS avatar. */
- avatarUrl?: string | null
-}
-
-/** ENS options supported by SSX. */
-export interface SSXEnsResolveOptions {
- /** Enable ENS name/domain resolution. */
- domain?: boolean;
- /** Enable ENS avatar resolution. */
- avatar?: boolean;
-}
-
-/** ENS options supported by SSX. */
-export interface SSXEnsConfig {
- /** Enable the ENS resolution on server instead of on client. */
- resolveOnServer?: boolean;
- /** ENS resolution options. True means resolve all. */
- resolve: SSXEnsResolveOptions;
-}
\ No newline at end of file
diff --git a/packages/ssx-sdk/tsconfig.json b/packages/ssx-sdk/tsconfig.json
index efee40a1..506bc079 100644
--- a/packages/ssx-sdk/tsconfig.json
+++ b/packages/ssx-sdk/tsconfig.json
@@ -1,102 +1,13 @@
{
- "include": ["src/**/*"],
- "exclude": ["node_modules/", "dist/**/*"],
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Enable incremental compilation */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- "lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
- // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "resolveJsonModule": true, /* Enable importing .json files */
- // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- // "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
- // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
- // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
}
}
diff --git a/packages/ssx-server/.eslintrc b/packages/ssx-server/.eslintrc
index 15880450..3a26ab40 100644
--- a/packages/ssx-server/.eslintrc
+++ b/packages/ssx-server/.eslintrc
@@ -1,14 +1,8 @@
{
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "ecmaVersion": 2020,
- "sourceType": "module"
- },
"extends": [
- "plugin:@typescript-eslint/recommended",
- "plugin:prettier/recommended"
+ "../../.eslintrc",
],
- "rules": {
- // e.g. "@typescript-eslint/explicit-function-return-type": "off",
- }
+ "env": {
+ "node": true,
+ },
}
diff --git a/packages/ssx-server/api-extractor.json b/packages/ssx-server/api-extractor.json
index 8db7226c..c97ca777 100644
--- a/packages/ssx-server/api-extractor.json
+++ b/packages/ssx-server/api-extractor.json
@@ -60,7 +60,7 @@
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
* local files for library1.
*/
- "bundledPackages": ["@spruceid/ssx-wasm"], // fix TSdoc Errors in SIWE we can have relevant siwe docs generated as well
+ "bundledPackages": ["@spruceid/ssx-core"], // fix TSdoc Errors in SIWE we can have relevant siwe docs generated as well
// "bundledPackages": ["@spruceid/siwe", "@spruceid/ssx-wasm"],
/**
diff --git a/packages/ssx-server/package.json b/packages/ssx-server/package.json
index 09520f26..3e9863c9 100644
--- a/packages/ssx-server/package.json
+++ b/packages/ssx-server/package.json
@@ -23,6 +23,7 @@
"ssx-server": "bin/ssx-server.js"
},
"dependencies": {
+ "@spruceid/ssx-core": "*",
"@spruceid/ssx-gnosis-extension": "*",
"axios": "^0.27.2",
"body-parser": "^1.20.0",
diff --git a/packages/ssx-server/src/index.ts b/packages/ssx-server/src/index.ts
index 5795a338..81103fcb 100644
--- a/packages/ssx-server/src/index.ts
+++ b/packages/ssx-server/src/index.ts
@@ -1,3 +1,10 @@
export * from './server';
-export * from './types';
export * from './middlewares';
+export * from '@spruceid/ssx-core/dist/types';
+export * from '@spruceid/ssx-core/dist/server/types';
+export {
+ /** @deprecated use SSXServerConfig field instead */
+ SSXServerConfig as SSXConfig,
+ /** @deprecated use SSXServerProviders field instead */
+ SSXServerProviders as SSXProviders
+} from '@spruceid/ssx-core';
\ No newline at end of file
diff --git a/packages/ssx-server/src/middlewares/express/endpoints.ts b/packages/ssx-server/src/middlewares/express/endpoints.ts
index 1b2be9e6..1e023c4a 100644
--- a/packages/ssx-server/src/middlewares/express/endpoints.ts
+++ b/packages/ssx-server/src/middlewares/express/endpoints.ts
@@ -30,49 +30,54 @@ const ssxEndpoints = (ssx: SSXServer) => {
* @param {Response} res
*/
router.post('/ssx-login', async function (req: Request, res: Response) {
- try {
- if (!req.body) {
- res.status(422).json({ message: 'Expected body.' });
- return;
- }
- if (!req.body.signature) {
- res
- .status(422)
- .json({ message: 'Expected the field `signature` in body.' });
- return;
- }
- if (!req.body.siwe) {
- res
- .status(422)
- .json({ message: 'Expected the field `siwe` in the body.' });
- return;
- }
+ if (!req.body) {
+ res.status(422).json({ message: 'Expected body.' });
+ return;
+ }
+ if (!req.body.signature) {
+ res
+ .status(422)
+ .json({ message: 'Expected the field `signature` in body.' });
+ return;
+ }
+ if (!req.body.siwe) {
+ res
+ .status(422)
+ .json({ message: 'Expected the field `siwe` in the body.' });
+ return;
+ }
- const { success, error, session } = await ssx.login(
+ let ssxLoginResponse;
+
+ try {
+ ssxLoginResponse = await ssx.login(
req.body.siwe,
req.body.signature,
req.body.daoLogin,
req.body.resolveEns,
req.session.nonce,
);
+ } catch (error) {
+ return res.status(500).json({ message: error.message });
+ }
+
+ const { success, error, session } = ssxLoginResponse;
- if (!success) {
- let message: string = error.type;
- if (error.expected && error.received) {
- message += ` Expected: ${error.expected}. Received: ${error.received}`;
- }
- return res.status(400).json({ message });
+ if (!success) {
+ let message: string = error.type;
+ if (error.expected && error.received) {
+ message += ` Expected: ${error.expected}. Received: ${error.received}`;
}
+ return res.status(400).json({ message });
+ }
- req.session.siwe = session.siwe;
- req.session.signature = session.signature;
- req.session.daoLogin = session.daoLogin;
- req.session.ens = session.ens;
+ req.session.siwe = session.siwe;
+ req.session.signature = session.signature;
+ req.session.daoLogin = session.daoLogin;
+ req.session.ens = session.ens;
- res.status(200).json({ ...req.session });
- } catch (error) {
- res.status(500).json({ message: error.message });
- }
+ res.status(200).json({ ...req.session });
+ return;
});
/**
@@ -84,12 +89,16 @@ const ssxEndpoints = (ssx: SSXServer) => {
router.post('/ssx-logout', async function (req: Request, res: Response) {
try {
req.session.destroy(null);
- req.session = null;
+ } catch (error) {
+ res.status(500).json({ message: error.message });
+ }
+ req.session = null;
+ try {
await req.ssx.logout();
- res.status(204).send();
} catch (error) {
res.status(500).json({ message: error.message });
}
+ res.status(204).send();
});
return router;
diff --git a/packages/ssx-server/src/middlewares/express/middleware.ts b/packages/ssx-server/src/middlewares/express/middleware.ts
index 988f3f5e..21be6f60 100644
--- a/packages/ssx-server/src/middlewares/express/middleware.ts
+++ b/packages/ssx-server/src/middlewares/express/middleware.ts
@@ -1,7 +1,7 @@
import { SSXServer } from '../../server';
import { SiweMessage } from 'siwe';
import { NextFunction, Request, Response } from 'express';
-import { SSXEnsData, SSXLogFields } from '../../types';
+import { SSXEnsData, SSXLogFields } from '@spruceid/ssx-core';
import { SiweGnosisVerify } from '@spruceid/ssx-gnosis-extension';
declare global {
@@ -87,28 +87,28 @@ export const ssxMiddleware = (ssx: SSXServer) => {
};
if (req.session?.siwe) {
+ const { signature, siwe, daoLogin, nonce } = req.session;
+ let siweMessageVerify;
try {
- const { signature, siwe, daoLogin, nonce } = req.session;
- const { success: verified, data } = await new SiweMessage(siwe).verify(
+ siweMessageVerify = await new SiweMessage(siwe).verify(
{ signature, nonce },
{
verificationFallback: daoLogin ? SiweGnosisVerify : null,
provider: ssx.provider,
},
);
-
- if (verified) {
- req.ssx = {
- ...req.ssx,
- siwe: data,
- verified,
- userId: `did:pkh:eip155:${siwe.chainId}:${siwe.address}`,
- };
- } else {
- req.session.destroy(() => next());
- }
} catch (error) {
- // ignore errors? Log them?
+ }
+ const { success: verified, data } = siweMessageVerify;
+ if (verified) {
+ req.ssx = {
+ ...req.ssx,
+ siwe: data,
+ verified,
+ userId: `did:pkh:eip155:${siwe.chainId}:${siwe.address}`,
+ };
+ } else {
+ req.session.destroy(() => next());
}
}
next();
diff --git a/packages/ssx-server/src/middlewares/http/index.ts b/packages/ssx-server/src/middlewares/http/index.ts
index b93573f0..f4159a0c 100644
--- a/packages/ssx-server/src/middlewares/http/index.ts
+++ b/packages/ssx-server/src/middlewares/http/index.ts
@@ -42,7 +42,7 @@ function getBody(req: IncomingMessage): Promise {
*/
export const SSXHttpMiddleware = (ssx: SSXServer) => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
- return (requestListener = (req, res) => {}) => {
+ return (requestListener = (req, res) => { }) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return async (req: IncomingMessage, res: ServerResponse) => {
// session middleware
@@ -57,9 +57,10 @@ export const SSXHttpMiddleware = (ssx: SSXServer) => {
};
if (req.session?.siwe) {
+ const { signature, siwe, daoLogin, nonce } = req.session;
+ let siweMessageVerification;
try {
- const { signature, siwe, daoLogin, nonce } = req.session;
- const { success: verified, data } = await new SiweMessage(
+ siweMessageVerification = await new SiweMessage(
siwe,
).verify(
{ signature, nonce },
@@ -68,19 +69,18 @@ export const SSXHttpMiddleware = (ssx: SSXServer) => {
provider: ssx.provider,
},
);
-
- if (verified) {
- req.ssx = {
- ...req.ssx,
- siwe: data,
- verified,
- userId: `did:pkh:eip155:${siwe.chainId}:${siwe.address}`,
- };
- } else {
- req.session.destroy(() => {});
- }
} catch (error) {
- // ignore errors? Log them?
+ }
+ const { success: verified, data } = siweMessageVerification;
+ if (verified) {
+ req.ssx = {
+ ...req.ssx,
+ siwe: data,
+ verified,
+ userId: `did:pkh:eip155:${siwe.chainId}:${siwe.address}`,
+ };
+ } else {
+ req.session.destroy(() => { });
}
}
diff --git a/packages/ssx-server/src/server.ts b/packages/ssx-server/src/server.ts
index 6c2167b2..f306c79b 100644
--- a/packages/ssx-server/src/server.ts
+++ b/packages/ssx-server/src/server.ts
@@ -1,8 +1,16 @@
import { generateNonce, SiweError, SiweMessage } from 'siwe';
import { SiweGnosisVerify } from '@spruceid/ssx-gnosis-extension';
import axios, { AxiosInstance } from 'axios';
-import { SSXLogFields, SSXServerConfig, SSXEventLogTypes, SSXEnsData, SSXEnsResolveOptions } from './types';
-import { getProvider } from './utils';
+import {
+ SSXLogFields,
+ SSXServerConfig,
+ SSXEventLogTypes,
+ SSXEnsData,
+ SSXEnsResolveOptions,
+ ssxLog,
+ ssxResolveEns,
+ getProvider
+} from '@spruceid/ssx-core';
import { ethers, utils } from 'ethers';
import { SessionData, SessionOptions } from 'express-session';
import session from 'express-session';
@@ -13,13 +21,15 @@ import { EventEmitter } from 'events';
* SSX-Server is a server-side library made to work with the SSX client libraries.
* SSX-Server is the base class that takes in a configuration object and works
* with various middleware libraries to add authentication and metrics to your server.
- *
- **/
+ */
export class SSXServer extends EventEmitter {
+ /** SSXServerConfig object. */
private _config: SSXServerConfig;
+ /** Axios instance. */
private _api: AxiosInstance;
+ /** EthersJS provider. */
public provider: ethers.providers.BaseProvider;
- /** session is a configured instance of express-session middleware */
+ /** Session is a configured instance of express-session middleware. */
public session: RequestHandler;
constructor(config: SSXServerConfig = {}) {
@@ -50,32 +60,22 @@ export class SSXServer extends EventEmitter {
}
}
- /** Set default values for optional configurations */
- private _setDefaults = () => {
+ /**
+ * Sets default values for optional configurations
+ */
+ private _setDefaults = (): void => {
this._config = {};
this._config.providers = {};
this._config.useSecureCookies = process.env.NODE_ENV === 'production';
};
- /**
- * Abstracts the fetch API to append correct headers, host and parse
- * responses to JSON for POST requests.
+ /**
+ * Registers a new event to the API
+ * @param data - SSXLogFields object.
+ * @returns True (success) or false (fail).
*/
- private _post = (route: string, body: any): Promise => {
- return this._api
- .post(route, typeof body === 'string' ? body : JSON.stringify(body))
- .then((res) => res.status === 204)
- .catch((e) => {
- return false;
- });
- };
-
- /** Registers a new event to the API */
public log = async (data: SSXLogFields): Promise => {
- if (!data.timestamp) data.timestamp = new Date().toISOString();
- return (
- this._config.providers?.metrics?.apiKey && this._post('/events', data)
- );
+ return ssxLog(this._api, this._config.providers?.metrics?.apiKey, data);
};
/**
@@ -89,6 +89,12 @@ export class SSXServer extends EventEmitter {
/**
* Verifies the SIWE message, signature, and nonce for a sign-in request.
* If the message is verified, a session token is generated and returned.
+ * @param siwe - SIWE Message.
+ * @param signature - The signature of the SIWE message.
+ * @param daoLogin - Whether or not daoLogin is enabled.
+ * @param resolveEns - Resolve ENS settings.
+ * @param nonce - nonce string.
+ * @returns Request data with SSX Server Session.
*/
public login = async (
siwe: SiweMessage | string,
@@ -101,86 +107,79 @@ export class SSXServer extends EventEmitter {
error: SiweError;
session: Partial;
}> => {
- // TODO(w4ll3): Refactor this function.
- let smartContractWalletOrCustomMethod = false;
- try {
- const siweMessage = new SiweMessage(siwe);
- let siweMessageVerifyPromise: any = siweMessage.verify(
- { signature, nonce },
- {
- verificationFallback: daoLogin ? SiweGnosisVerify : undefined,
- provider: this.provider,
- },
- )
- .then(data => data)
- .catch(error => {
- console.error(error);
- throw error;
- });
+ const siweMessage = new SiweMessage(siwe);
- let ens: SSXEnsData = {};
- let promises: Array> = [siweMessageVerifyPromise];
- if (resolveEns) {
- let resolveEnsOpts;
- if (resolveEns !== true) {
- resolveEnsOpts = resolveEns;
- }
- promises.push(this.resolveEns(siweMessage.address, resolveEnsOpts));
- }
- try {
- siweMessageVerifyPromise = await Promise.all(promises)
- .then(([siweMessageVerify, ensData]) => {
- ens = ensData
- return siweMessageVerify;
- });
- } catch (error) {
+ let siweMessageVerifyPromise: any = siweMessage.verify(
+ { signature, nonce },
+ {
+ verificationFallback: daoLogin ? SiweGnosisVerify : undefined,
+ provider: this.provider,
+ },
+ )
+ .then(data => data)
+ .catch(error => {
console.error(error);
+ throw error;
+ });
+
+ let ens: SSXEnsData = {};
+ let promises: Array> = [siweMessageVerifyPromise];
+ if (resolveEns) {
+ let resolveEnsOpts;
+ if (resolveEns !== true) {
+ resolveEnsOpts = resolveEns;
}
+ promises.push(this.resolveEns(siweMessage.address, resolveEnsOpts));
+ }
+ try {
+ siweMessageVerifyPromise = await Promise.all(promises)
+ .then(([siweMessageVerify, ensData]) => {
+ ens = ensData
+ return siweMessageVerify;
+ });
+ } catch (error) {
+ console.error(error);
+ }
- const { success, error, data } = siweMessageVerifyPromise;
+ const { success, error, data } = siweMessageVerifyPromise;
+ let smartContractWalletOrCustomMethod = false;
+ try {
+ // TODO: Refactor this function.
/** This addresses the cases where having DAOLogin
* enabled would make all the logs to be of Gnosis Type
**/
smartContractWalletOrCustomMethod = !(
utils.verifyMessage(data.prepareMessage(), signature) === data.address
);
+ } catch (error) {
+ console.error(error);
+ }
- const event = {
- userId: `did:pkh:eip155:${data.chainId}:${data.address}`,
- type: SSXEventLogTypes.LOGIN,
- content: {
- signature,
- siwe,
- isGnosis: daoLogin && smartContractWalletOrCustomMethod,
- },
- };
+ const event = {
+ userId: `did:pkh:eip155:${data.chainId}:${data.address}`,
+ type: SSXEventLogTypes.LOGIN,
+ content: {
+ signature,
+ siwe,
+ isGnosis: daoLogin && smartContractWalletOrCustomMethod,
+ },
+ };
- this.log(event);
- this.emit(event.type, event);
+ this.log(event);
+ this.emit(event.type, event);
- return {
- success,
- error,
- session: {
- siwe: new SiweMessage(siwe),
- signature: signature,
- daoLogin: daoLogin,
- ens,
- },
- };
- } catch (e) {
- return {
- success: false,
- error: e,
- session: {
- siwe: new SiweMessage(siwe),
- signature: signature,
- daoLogin: daoLogin,
- },
- };
- }
+ return {
+ success,
+ error,
+ session: {
+ siwe: new SiweMessage(siwe),
+ signature: signature,
+ daoLogin: daoLogin,
+ ens,
+ },
+ };
};
/**
@@ -192,47 +191,17 @@ export class SSXServer extends EventEmitter {
public resolveEns = async (
/* User Address */
address: string,
- resolveEnsOpts: {
- /* Enables ENS domain/name resolution */
- domain?: boolean,
- /* Enables ENS avatar resolution */
- avatar?: boolean,
- } = {
- domain: true,
- avatar: true
- }
+ /* ENS resolution settings */
+ resolveEnsOpts?: SSXEnsResolveOptions
): Promise => {
- if (!address) {
- throw new Error('Missing address.');
- }
- let ens: SSXEnsData = {};
- let promises: Array> = [];
- if (resolveEnsOpts?.domain) {
- promises.push(this.provider.lookupAddress(address))
- }
- if (resolveEnsOpts?.avatar) {
- promises.push(this.provider.getAvatar(address))
- }
-
- await Promise.all(promises)
- .then(([domain, avatarUrl]) => {
- if (!resolveEnsOpts.domain && resolveEnsOpts.avatar) {
- [domain, avatarUrl] = [undefined, domain];
- }
- if (domain) {
- ens['domain'] = domain;
- }
- if (avatarUrl) {
- ens['avatarUrl'] = avatarUrl;
- }
- });
-
- return ens;
- }
+ return ssxResolveEns(this.provider, address, resolveEnsOpts)
+ };
/**
* Logs out the user by deleting the session.
* Currently this is a no-op.
+ * @param destroySession - Method to remove session from storage.
+ * @returns Promise with true (success) or false (fail).
*/
public logout = async (
destroySession?: () => Promise,
@@ -240,6 +209,10 @@ export class SSXServer extends EventEmitter {
return destroySession?.();
};
+ /**
+ * Gets Express Session config params to configure the session.
+ * @returns Session options.
+ */
public getExpressSessionConfig = (): SessionOptions => {
return {
...this.getDefaultExpressSessionConfig(),
@@ -250,6 +223,10 @@ export class SSXServer extends EventEmitter {
};
};
+ /**
+ * Gets default Express Session Config.
+ * @returns Default session options
+ */
private getDefaultExpressSessionConfig = (): SessionOptions => ({
name: 'ssx-session-storage',
secret: this._config.signingKey,
diff --git a/packages/ssx-server/src/utils.ts b/packages/ssx-server/src/utils.ts
deleted file mode 100644
index 646ddfc4..00000000
--- a/packages/ssx-server/src/utils.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import {
- isSSXAlchemyProvider,
- isSSXAnkrProvider,
- isSSXCloudflareProvider,
- isSSXCustomProvider,
- isSSXEtherscanProvider,
- isSSXInfuraProvider,
- isSSXPocketProvider,
- SSXAlchemyProviderNetworks,
- SSXAnkrProviderNetworks,
- SSXEtherscanProviderNetworks,
- SSXInfuraProviderNetworks,
- SSXPocketProviderNetworks,
- SSXRPCProvider,
-} from './types';
-import { ethers } from 'ethers';
-
-/**
- * Returns an ethers provider based on the RPC configuration
- */
-export const getProvider = (rpc: SSXRPCProvider): ethers.providers.BaseProvider => {
- if (isSSXEtherscanProvider(rpc)) {
- return new ethers.providers.EtherscanProvider(
- rpc.network ?? SSXEtherscanProviderNetworks.MAINNET,
- rpc.apiKey,
- );
- }
- if (isSSXInfuraProvider(rpc)) {
- return new ethers.providers.InfuraProvider(
- rpc.network ?? SSXInfuraProviderNetworks.MAINNET,
- rpc.apiKey,
- );
- }
- if (isSSXAlchemyProvider(rpc)) {
- return new ethers.providers.AlchemyProvider(
- rpc.network ?? SSXAlchemyProviderNetworks.MAINNET,
- rpc.apiKey,
- );
- }
- if (isSSXCloudflareProvider(rpc)) {
- return new ethers.providers.CloudflareProvider();
- }
- if (isSSXPocketProvider(rpc)) {
- return new ethers.providers.PocketProvider(
- rpc.network ?? SSXPocketProviderNetworks.MAINNET,
- rpc.apiKey,
- );
- }
- if (isSSXAnkrProvider(rpc)) {
- return new ethers.providers.AnkrProvider(
- rpc.network ?? SSXAnkrProviderNetworks.MAINNET,
- rpc.apiKey,
- );
- }
- if (isSSXCustomProvider(rpc)) {
- return new ethers.providers.JsonRpcProvider(rpc.url, rpc.network);
- }
-};
diff --git a/packages/ssx-server/tsconfig.json b/packages/ssx-server/tsconfig.json
index b2b9bb9a..0bf32b40 100644
--- a/packages/ssx-server/tsconfig.json
+++ b/packages/ssx-server/tsconfig.json
@@ -1,19 +1,13 @@
{
-
- "include": ["src/**/*"],
- "exclude": ["node_modules", "dist"],
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Enable incremental compilation */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
"target": "ES5" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"lib": [
"es2019",
@@ -21,89 +15,9 @@
"ES6",
"DOM"
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
- // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
-
- /* Modules */
- "module": "CommonJS" /* Specify what module code is generated. */,
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
"rootDir": "./src", /* Specify the root folder within your source files. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "resolveJsonModule": true, /* Enable importing .json files */
- // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
-
- /* Emit */
- "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
- "declarationMap": true /* Create sourcemaps for d.ts files. */,
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true /* Create source map files for emitted JavaScript files. */,
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
-
- /* Type Checking */
- // "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
- // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
- // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
diff --git a/packages/ssx-serverless/.eslintrc b/packages/ssx-serverless/.eslintrc
index f6ad8eeb..77983042 100644
--- a/packages/ssx-serverless/.eslintrc
+++ b/packages/ssx-serverless/.eslintrc
@@ -1,13 +1,5 @@
{
- "root": true,
- "parser": "@typescript-eslint/parser",
- "plugins": [
- "@typescript-eslint"
- ],
"extends": [
- "eslint:recommended",
- "plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended",
- "prettier"
- ]
-}
\ No newline at end of file
+ "../../.eslintrc",
+ ],
+}
diff --git a/packages/ssx-serverless/api-extractor.json b/packages/ssx-serverless/api-extractor.json
index 21082dfe..c7ea0969 100644
--- a/packages/ssx-serverless/api-extractor.json
+++ b/packages/ssx-serverless/api-extractor.json
@@ -60,7 +60,7 @@
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
* local files for library1.
*/
- // "bundledPackages": ["@spruceid/ssx-gnosis-extension"], // fix TSdoc Errors in SIWE we can have relevant siwe docs generated as well
+ "bundledPackages": ["@spruceid/ssx-core"], // fix TSdoc Errors in SIWE we can have relevant siwe docs generated as well
/**
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
* will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
diff --git a/packages/ssx-serverless/package.json b/packages/ssx-serverless/package.json
index 2a149e40..0a72fe4d 100644
--- a/packages/ssx-serverless/package.json
+++ b/packages/ssx-serverless/package.json
@@ -28,8 +28,9 @@
},
"dependencies": {
"siwe": "^2.1.2",
+ "@spruceid/ssx-core": "*",
"@spruceid/ssx-gnosis-extension": "*",
- "axios": "^1.1.3"
+ "axios": "^0.27.2"
},
"devDependencies": {
"@microsoft/api-documenter": "^7.19.4",
diff --git a/packages/ssx-serverless/src/index.ts b/packages/ssx-serverless/src/index.ts
index b9952f37..552916c3 100644
--- a/packages/ssx-serverless/src/index.ts
+++ b/packages/ssx-serverless/src/index.ts
@@ -1,27 +1,41 @@
-import { generateNonce, SiweError, SiweMessage, SiweResponse } from 'siwe';
+import { generateNonce, SiweMessage } from 'siwe';
import { SiweGnosisVerify } from '@spruceid/ssx-gnosis-extension';
import axios, { AxiosInstance } from 'axios';
-import { SSXLogFields, SSXServerConfig, SSXEventLogTypes, SSXSessionCRUDConfig, SSXSessionData, SSXEnsData } from './types';
-import { getProvider } from './utils';
+import {
+ SSXServerConfig,
+ SSXSessionCRUDConfig,
+ SSXSessionData,
+ SSXEnsData as ISSXEnsData
+} from './types';
+import {
+ SSXLogFields,
+ SSXEventLogTypes,
+ ssxLog,
+ SSXEnsResolveOptions,
+ SSXEnsData,
+ getProvider,
+ ssxResolveEns
+} from '@spruceid/ssx-core';
import { ethers, utils } from 'ethers';
/**
* SSX-Server is a server-side library made to work with the SSX client libraries.
* SSX-Server is the base class that takes in a configuration object to add
* authentication and metrics to your server.
- *
- **/
+ */
export class SSXServer {
+ /** SSXServerConfig object. */
private _config: SSXServerConfig = {};
+ /** Axios instance. */
private _api: AxiosInstance;
- /** EthersJS provider */
+ /** EthersJS provider. */
public provider: ethers.providers.BaseProvider;
- /** Definition of CRUD functions for sessions */
+ /** Definition of CRUD functions for sessions. */
public session: SSXSessionCRUDConfig;
/**
- * @param config - Base configuration of the SSXServer
- * @param session - CRUD definition for session operations
+ * @param config - Base configuration of the SSXServer.
+ * @param session - CRUD definition for session operations.
* @example
* ```
* const ssx = new SSXServer({
@@ -66,24 +80,14 @@ export class SSXServer {
this.provider = getProvider(config.providers?.rpc);
}
- /**
- * Abstracts the fetch API to append correct headers, host and parse
- * responses to JSON for POST requests.
+ /**
+ * Registers a new event to the API.
+ * @param data - SSXLogFields JSON.
+ * @returns Promise with true (success) or false (fail).
*/
- private _post = (route: string, body: any): Promise => {
- return this._api
- .post(route, typeof body === 'string' ? body : JSON.stringify(body))
- .then((res) => res.status === 204)
- .catch((e) => {
- console.error(e);
- return false;
- });
- };
-
- /** Registers a new event to the API */
public log = async (data: SSXLogFields): Promise => {
- if (!data.timestamp) { data.timestamp = new Date().toISOString() };
- return !!this._config.providers?.metrics?.apiKey && this._post('/events', data);
+ this._api;
+ return ssxLog(this._api, this._config.providers?.metrics?.apiKey ?? '', data);
};
/**
@@ -94,33 +98,114 @@ export class SSXServer {
*/
public generateNonce = generateNonce;
+ /**
+ * Tries to update the session to store the new nonce.
+ * @param sessionKey - Session identifier.
+ * @param value - Value to update statement.
+ * @param opts - Optional parameters.
+ * @returns Object with update result.
+ */
+ private updateSessionNonce = async (
+ /* The session with this key will be updated. */
+ sessionKey: string,
+ /** Value for the update statement. */
+ value: any,
+ /* Optional parameters to be passed to session.update. */
+ opts: any
+ ): Promise<{
+ success: boolean;
+ dbResult: any;
+ }> => {
+ let dbResult;
+ try {
+ dbResult = await this.session.update(sessionKey, value, opts);
+ } catch (error) {
+ throw {
+ success: false,
+ dbResult: error
+ };
+ }
+ return {
+ success: true,
+ dbResult
+ };
+ };
+
+ /**
+ * Tries to create a session to store and store a nonce.
+ * @param value - Value for the create statement.
+ * @param opts - Optional parameters.
+ * @returns Object with create result.
+ */
+ private createSessionNonce = async (
+ /** Value for the create statement */
+ value: any,
+ /* Optional parameters to be passed to session.create. */
+ opts: any
+ ): Promise<{
+ success: boolean;
+ dbResult: any;
+ }> => {
+ let dbResult;
+ try {
+ dbResult = await this.session.create(value, opts);
+ } catch (error) {
+ throw {
+ success: false,
+ dbResult: error
+ };
+ }
+ return {
+ success: true,
+ dbResult
+ };
+ };
+
/**
* Generates a nonce and stores it in the current session
* if a sessionKey is provided or creates a new one if not.
+ * @param getNonceOpts - Optional params to configure session management.
+ * @returns Promise with nonce and database result.
*/
public getNonce = async (
getNonceOpts?: {
- /* If provided the session with this key will be updated */
+ /* If provided the session with this key will be updated. */
sessionKey?: any,
- /* A function that will return the value for the update statement */
+ /* A function that will return the value for the update statement. */
generateUpdateValue?: (nonce: string) => any,
- /* A function that will return the value for the create statement */
+ /* A function that will return the value for the create statement. */
generateCreateValue?: (nonce: string) => any,
- /* Optional parameters to be passed to session.create */
+ /* Optional parameters to be passed to session.create. */
createOpts?: Record,
- /* Optional parameters to be passed to session.update */
+ /* Optional parameters to be passed to session.update. */
updateOpts?: Record,
}): Promise<{ nonce: string, dbResult: any }> => {
const nonce = generateNonce();
let dbResult;
if (getNonceOpts) {
- try {
+
+ let updateSessionResponse;
+ if (getNonceOpts?.sessionKey) {
const updateValue = getNonceOpts.generateUpdateValue?.(nonce) ?? nonce;
- dbResult = await this.session.update(getNonceOpts.sessionKey, updateValue, getNonceOpts?.updateOpts);
- } catch (error) {
+ try {
+ updateSessionResponse = await this.updateSessionNonce(getNonceOpts?.sessionKey, updateValue, getNonceOpts?.updateOpts);
+ } catch (error) {
+ updateSessionResponse = error;
+ }
+ }
+ /*
+ If I don't have a sessionKey (to update)
+ OR
+ I have a sessionKey (to update) but the update returned success=false
+ */
+ if (!getNonceOpts.sessionKey || (getNonceOpts.sessionKey && !updateSessionResponse?.success)) {
const createValue = getNonceOpts.generateCreateValue?.(nonce) ?? { nonce, address: getNonceOpts.sessionKey };
- dbResult = await this.session.create(createValue, getNonceOpts?.createOpts);
+ try {
+ dbResult = (await this.createSessionNonce(createValue, getNonceOpts?.createOpts)).dbResult;
+ } catch (error) {
+ dbResult = error.dbResult;
+ }
}
}
@@ -130,29 +215,29 @@ export class SSXServer {
/**
* Verifies the SIWE message, signature, and nonce for a sign-in request.
* If the message is verified, a session token is generated and returned.
- * @param siwe - Object containing the siwe fields or EIP-4361 message
- * @param signature - Signature of the EIP-4361 message
- * @param sessionKey - Key used to index user's session
- * @param signInOpts - Additional options to customize sign-in behavior
- * @returns Object containing information about the session
+ * @param siwe - Object containing the siwe fields or EIP-4361 message.
+ * @param signature - Signature of the EIP-4361 message.
+ * @param sessionKey - Key used to index user's session.
+ * @param signInOpts - Additional options to customize sign-in behavior.
+ * @returns Object containing information about the session.
*/
public signIn = async (
siwe: SiweMessage | string,
signature: string,
- /* Session key to be used in session lookup */
+ /* Session key to be used in session lookup. */
sessionKey: any,
signInOpts: {
- /* Enables lookup for delegations */
+ /* Enables lookup for delegations. */
daoLogin?: boolean,
- /* Enables ENS Domain resolution */
+ /* Enables ENS Domain resolution. */
resolveEnsDomain?: boolean,
- /* Enables ENS Avatar resolution */
+ /* Enables ENS Avatar resolution. */
resolveEnsAvatar?: boolean,
- /* Optional parameters to be passed to session.retrieve */
+ /* Optional parameters to be passed to session.retrieve. */
retrieveOpts?: Record,
- /* A function that will return the value for the update statement */
+ /* A function that will return the value for the update statement. */
generateUpdateValue?: (sessionData: SSXSessionData) => any,
- /* Optional parameters to be passed to session.create */
+ /* Optional parameters to be passed to session.create. */
updateOpts?: Record,
},
): Promise => {
@@ -179,25 +264,25 @@ export class SSXServer {
throw error;
});
- let ens: SSXEnsData = {};
+ let ens: ISSXEnsData = {};
let promises: Array> = [siweMessageVerifyPromise];
- try {
- if (signInOpts?.resolveEnsDomain) {
- promises.push(this.provider.lookupAddress(siweMessage.address))
- }
- if (signInOpts?.resolveEnsAvatar) {
- promises.push(this.provider.getAvatar(siweMessage.address))
+
+ if (signInOpts?.resolveEnsDomain || signInOpts?.resolveEnsAvatar) {
+ const resolveEnsOpts = {
+ domain: signInOpts?.resolveEnsDomain,
+ avatar: signInOpts?.resolveEnsAvatar,
}
+ promises.push(this.resolveEns(siweMessage.address, resolveEnsOpts));
+ }
+
+ try {
siweMessageVerifyPromise = await Promise.all(promises)
- .then(([siweMessageVerify, ensName, ensAvatarUrl]) => {
- if (!signInOpts.resolveEnsDomain && signInOpts.resolveEnsAvatar) {
- [ensName, ensAvatarUrl] = [undefined, ensName];
+ .then(([siweMessageVerify, ensData]) => {
+ if (ensData.domain) {
+ ens['ensName'] = ensData.domain;
}
- if (ensName) {
- ens['ensName'] = ensName;
- }
- if (ensAvatarUrl) {
- ens['ensAvatarUrl'] = ensAvatarUrl;
+ if (ensData.avatarUrl) {
+ ens['ensAvatarUrl'] = ensData.avatarUrl;
}
return siweMessageVerify;
});
@@ -216,45 +301,60 @@ export class SSXServer {
ens
};
+ const updateValue = signInOpts.generateUpdateValue?.(sessionData) ?? sessionData;
try {
- const updateValue = signInOpts.generateUpdateValue?.(sessionData) ?? sessionData;
await this.session.update(sessionKey, updateValue, signInOpts?.updateOpts);
} catch (error) {
console.error(error);
throw error;
}
+ let smartContractWalletOrCustomMethod = false;
try {
- // TODO(w4ll3): Refactor this function.
+ // TODO: Refactor this function.
/** This addresses the cases where having DAOLogin
* enabled would make all the logs to be of Gnosis Type
**/
- let smartContractWalletOrCustomMethod = false;
smartContractWalletOrCustomMethod = !(
utils.verifyMessage(siweMessage.prepareMessage(), signature) === siweMessage.address
);
-
- this.log({
- userId: `did:pkh:eip155:${siweMessage.chainId}:${siweMessage.address}`,
- type: SSXEventLogTypes.LOGIN,
- content: {
- signature,
- siwe,
- isGnosis: signInOpts?.daoLogin && smartContractWalletOrCustomMethod,
- },
- });
} catch (error) {
console.error(error);
}
+ this.log({
+ userId: `did:pkh:eip155:${siweMessage.chainId}:${siweMessage.address}`,
+ type: SSXEventLogTypes.LOGIN,
+ content: {
+ signature,
+ siwe,
+ isGnosis: signInOpts?.daoLogin && smartContractWalletOrCustomMethod,
+ },
+ });
+
return sessionData;
};
/**
- * Calls the delete function to delete the user's session
- * @param sessionKey - Key used to index sessions
+ * ENS data supported by SSX.
+ * @param address - User address.
+ * @param resolveEnsOpts - Options to resolve ENS.
+ * @returns Object containing ENS data.
+ */
+ public resolveEns = async (
+ /* User Address */
+ address: string,
+ /* ENS resolution settings */
+ resolveEnsOpts?: SSXEnsResolveOptions
+ ): Promise => {
+ return ssxResolveEns(this.provider, address, resolveEnsOpts)
+ };
+
+ /**
+ * Calls the delete function to delete the user's session.
+ * @param sessionKey - Key used to index sessions.
* @param deleteOpts - Additional options to be passed to the seeion.delete function.
- * @returns The result of session.delete
+ * @returns The result of session.delete.
* @example
* signOut("0x9D85ca56217D2bb651b00f15e694EB7E713637D4")
*/
@@ -271,7 +371,7 @@ export class SSXServer {
* @param sessionKey - Key used to index sessions.
* @param getSSXDataFromSession - Function that will parse the resolved value from
* session into SSXSessionData if the a custom session structure is being used.
- * @returns SSXSessionData
+ * @returns SSXSessionData.
*/
public me = async (sessionKey: any, getSSXDataFromSession?: (session: any) => SSXSessionData) => {
const dbResult = await this.session.retrieve(sessionKey);
@@ -279,15 +379,21 @@ export class SSXServer {
throw new Error('Unable to retrieve session.');
}
let session: SSXSessionData;
+ let castingError: any;
try {
session = dbResult as SSXSessionData;
} catch (error) {
+ castingError = error;
+ }
+
+ if (!session) {
if (!getSSXDataFromSession) {
- console.error(error);
- throw error;
+ console.error(castingError);
+ throw castingError;
}
session = getSSXDataFromSession(dbResult);
}
+
const siweMessage = new SiweMessage(session.siweMessage);
await siweMessage.verify(
{ signature: session.signature },
@@ -300,5 +406,19 @@ export class SSXServer {
}
}
-export * from "./types";
-export * from "./utils";
+export * from "@spruceid/ssx-core/dist/types";
+export {
+ SSXLogFields,
+ SSXEventLogTypes
+};
+export {
+ SSXSessionCRUDConfig,
+ SSXSessionData,
+ SSXEnsData,
+ SSXServerConfig,
+ /** @deprecated use SSXServerConfig field instead */
+ SSXServerConfig as SSXConfig,
+ SSXServerProviders,
+ /** @deprecated use SSXServerProviders field instead */
+ SSXServerProviders as SSXProviders
+} from './types';
\ No newline at end of file
diff --git a/packages/ssx-serverless/src/types.ts b/packages/ssx-serverless/src/types.ts
index 7e0dfc1a..ab03a667 100644
--- a/packages/ssx-serverless/src/types.ts
+++ b/packages/ssx-serverless/src/types.ts
@@ -1,217 +1,23 @@
-import { providers } from 'ethers';
-import { ConnectionInfo } from 'ethers/lib/utils';
import { SiweMessage } from 'siwe';
+import { SSXRPCProvider, SSXMetricsProvider } from '@spruceid/ssx-core';
+// TODO: unify with ssx-server
/** Configuration interface for ssx-server */
export interface SSXServerConfig {
/** Connection to a cryptographic keypair and/or network. */
- providers?: SSXProviders;
+ providers?: SSXServerProviders;
/** Enable lookup for delegations in the DelegateRegistry SC*/
daoLogin?: boolean;
}
/** SSX web3 configuration settings */
-export interface SSXProviders {
+export interface SSXServerProviders {
/** JSON RPC provider configurations */
rpc?: SSXRPCProvider;
/** Metrics service configurations */
metrics?: SSXMetricsProvider;
}
-export type SSXRPCProvider =
- | SSXGenericProvider
- | SSXEtherscanProvider
- | SSXInfuraProvider
- | SSXAlchemyProvider
- | SSXCloudflareProvider
- | SSXPocketProvider
- | SSXAnkrProvider
- | SSXCustomProvider;
-
-/** Enum of supported RPC providers */
-export enum SSXRPCProviders {
- SSXAlchemyProvider = 'alchemy',
- SSXAnkrProvider = 'ankr',
- SSXCloudflareProvider = 'cloudflare',
- SSXCustomProvider = 'custom',
- SSXEtherscanProvider = 'etherscan',
- SSXInfuraProvider = 'infura',
- SSXPocketProvider = 'pocket',
-}
-
-/** Enum of supported networks for Etherscan */
-export enum SSXEtherscanProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
-}
-
-/** Etherscan provider settings */
-export type SSXEtherscanProvider = {
- service: SSXRPCProviders.SSXEtherscanProvider;
- apiKey?: string;
- network?: SSXEtherscanProviderNetworks;
-};
-
-/* Type-Guard for SSXEtherScanProvider */
-export const isSSXEtherscanProvider = (provider: SSXRPCProvider):
- provider is SSXEtherscanProvider => provider.service === SSXRPCProviders.SSXEtherscanProvider;
-
-/** Enum of supported networks for Infura */
-export enum SSXInfuraProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
- POLYGON = 'matic',
- POLYGON_MUMBAI = 'maticmum',
- OPTIMISM = 'optimism',
- OPTIMISM_KOVAN = 'optimism-kovan',
- ARBITRUM = 'arbitrum',
- ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
-}
-
-/** Infura provider project settings */
-export type SSXInfuraProviderProjectSettings = {
- projectId: string;
- projectSecret: string;
-};
-
-/** Infura provider settings */
-export type SSXInfuraProvider = {
- service: SSXRPCProviders.SSXInfuraProvider;
- apiKey: string | SSXInfuraProviderProjectSettings;
- network?: SSXInfuraProviderNetworks;
-};
-
-/* Type-Guard for SSXInfuraProvider */
-export const isSSXInfuraProvider = (provider: SSXRPCProvider):
- provider is SSXInfuraProvider => provider.service === SSXRPCProviders.SSXInfuraProvider;
-
-/** Enum of supported networks for Alchemy */
-export enum SSXAlchemyProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
- KOVAN = 'kovan',
- POLYGON = 'matic',
- POLYGON_MUMBAI = 'maticmum',
- OPTIMISM = 'optimism',
- OPTIMISM_KOVAN = 'optimism-kovan',
- ARBITRUM = 'arbitrum',
- ARBITRUM_RINKEBY = 'arbitrum-rinkeby',
-}
-
-/** Alchemy provider settings */
-export type SSXAlchemyProvider = {
- service: SSXRPCProviders.SSXAlchemyProvider;
- apiKey?: string;
- network?: SSXAlchemyProviderNetworks;
-};
-
-/* Type-Guard for SSXAlchemyProvider */
-export const isSSXAlchemyProvider = (provider: SSXRPCProvider):
- provider is SSXAlchemyProvider => provider.service === SSXRPCProviders.SSXAlchemyProvider;
-
-/** Cloudflare provider settings */
-export type SSXCloudflareProvider = {
- service: SSXRPCProviders.SSXCloudflareProvider;
-};
-
-/* Type-Guard for SSXCloudflareProvider */
-export const isSSXCloudflareProvider = (provider: SSXRPCProvider):
- provider is SSXCloudflareProvider => provider.service === SSXRPCProviders.SSXCloudflareProvider;
-
-/** Enum of supported networks for Pocket */
-export enum SSXPocketProviderNetworks {
- MAINNET = 'homestead',
- ROPSTEN = 'ropsten',
- RINKEBY = 'rinkeby',
- GOERLI = 'goerli',
-}
-
-/** Pocket provider settings */
-export type SSXPocketProvider = {
- service: SSXRPCProviders.SSXPocketProvider;
- apiKey?: string;
- network?: SSXPocketProviderNetworks;
-};
-
-/* Type-Guard for SSXPocketProvider */
-export const isSSXPocketProvider = (provider: SSXRPCProvider):
- provider is SSXPocketProvider => provider.service === SSXRPCProviders.SSXPocketProvider;
-
-/** Enum of supported networks for Ankr */
-export enum SSXAnkrProviderNetworks {
- MAINNET = 'homestead',
- POLYGON = 'matic',
- ARBITRUM = 'arbitrum',
-}
-
-/** Ankr provider settings */
-export type SSXAnkrProvider = {
- service: SSXRPCProviders.SSXAnkrProvider;
- apiKey?: string;
- network?: SSXAnkrProviderNetworks;
-};
-
-/* Type-Guard for SSXAnkrProvider */
-export const isSSXAnkrProvider = (provider: SSXRPCProvider):
- provider is SSXAnkrProvider => provider.service === SSXRPCProviders.SSXAnkrProvider;
-
-/** Custom provider settings */
-export type SSXCustomProvider = {
- service: SSXRPCProviders.SSXCustomProvider;
- url?: string | ConnectionInfo;
- network?: providers.Networkish;
-};
-
-/* Type-Guard for SSXCustomProvider */
-export const isSSXCustomProvider = (provider: SSXRPCProvider):
- provider is SSXCustomProvider => provider.service === SSXRPCProviders.SSXCustomProvider;
-
-/** Generic provider settings */
-export type SSXGenericProvider = {
- service: SSXRPCProviders;
- url?: string | ConnectionInfo;
- network?: providers.Networkish;
- apiKey?: string | SSXInfuraProviderProjectSettings;
-};
-
-/** SSX Metrics Provider settings */
-export type SSXMetricsProvider = {
- service: 'ssx';
- apiKey: string;
-};
-
-/** Allowed fields for an SSX Log */
-export interface SSXLogFields {
- /** Unique identifier for the user, formatted as a DID */
- userId: string;
- /** RFC-3339 time of resource generation, defaults to now */
- timestamp?: string;
- /** Type of content being logged */
- type: SSXEventLogTypes;
- /** Any JSON stringifiable structure to be logged */
- content: string | Record;
-}
-
-/** Available SSX Log Types */
-export enum SSXEventLogTypes {
- /** Login type definition */
- LOGIN = 'ssx-login',
- /** Logout type definition */
- // LOGOUT = "ssx-logout",
- /** Logging type definition */
- // LOG = "LOG",
- /** Event type definition */
- // EVENT = "event",
-}
-
/**
* Type definition for CRUD session functions
* @example
diff --git a/packages/ssx-serverless/tsconfig.json b/packages/ssx-serverless/tsconfig.json
index b4858dec..af73b91b 100644
--- a/packages/ssx-serverless/tsconfig.json
+++ b/packages/ssx-serverless/tsconfig.json
@@ -1,104 +1,15 @@
{
- "exclude": [ "example", "dist", "node_modules" ],
+ "extends": "../../tsconfig.json",
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules/",
+ "dist/**/*"
+ ],
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- // "rootDir": "./", /* Specify the root folder within your source files. */
- // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- // "removeComments": true, /* Disable emitting comments. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
- // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "outDir": "./dist", /* Specify an output folder for all emitted files. */
}
-}
+ // // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "strict": true, /* Enable all strict type-checking options. */
+}
\ No newline at end of file
diff --git a/scripts/build-docs.js b/scripts/build-docs.js
index db008de2..2f8eeb38 100644
--- a/scripts/build-docs.js
+++ b/scripts/build-docs.js
@@ -15,7 +15,12 @@ const getLines = (output, prefix = 'reference/ssx-sdk/', layer = 0) => {
const generateReference = async () => {
const output = {};
- const dirs = [ './documentation/reference/ssx-sdk', './documentation/reference/ssx-server', './documentation/reference/ssx-serverless'];
+ const dirs = [
+ './documentation/reference/ssx-sdk',
+ './documentation/reference/ssx-core',
+ './documentation/reference/ssx-server',
+ './documentation/reference/ssx-serverless',
+ ];
const docFiles = [ ...(await Promise.all(dirs.map(async dir => await readdir(dir)))) ].reduce((p, c) => [...p, ...c], []);
for (const docFile of docFiles) {
@@ -58,12 +63,14 @@ const generateReference = async () => {
const lines = [
"## Reference",
...getLines({ 'ssx': output['ssx'] }),
+ ...getLines({ 'ssx-core': output['ssx-core']}, 'reference/ssx-core/'),
...getLines({ 'ssx-server': output['ssx-server']}, 'reference/ssx-server/'),
...getLines({ 'ssx-serverless': output['ssx-serverless']}, 'reference/ssx-serverless/'),
];
let reference = lines.join('\n');
reference = reference.replace('* [ssx]', '* [SSX API Reference]');
+ reference = reference.replace('* [ssx-core]', '* [SSX Core API Reference]');
reference = reference.replace('* [ssx-server]', '* [SSX Server API Reference]');
reference = reference.replace('* [ssx-serverless]', '* [SSX Serverless API Reference]');
return reference;
@@ -76,6 +83,7 @@ const generateSUMMARY = async () => {
let reference = await generateReference();
reference = reference.replace(/^\* \[ssx\]/, '* [SSX API Reference]');
+ reference = reference.replace(/^\* \[ssx-core\]/, '* [SSX Core API Reference]');
reference = reference.replace(/^\* \[ssx-server\]/, '* [SSX Server API Reference]');
reference = reference.replace(/^\* \[ssx-serverless\]/, '* [SSX Serverless API Reference]');
await writeFile('./documentation/SUMMARY.md', previous.concat(reference));
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..2fd5432b
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ "lib": [
+ "es2019"
+ ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ "module": "commonjs", /* Specify what module code is generated. */
+ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ }
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index a0cba5d5..0e86aacc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -724,7 +724,28 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30"
integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==
-"@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
+"@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113"
+ integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==
+ dependencies:
+ "@ampproject/remapping" "^2.1.0"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.5"
+ "@babel/helper-compilation-targets" "^7.20.0"
+ "@babel/helper-module-transforms" "^7.20.2"
+ "@babel/helpers" "^7.20.5"
+ "@babel/parser" "^7.20.5"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.20.5"
+ "@babel/types" "^7.20.5"
+ convert-source-map "^1.7.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.1"
+ semver "^6.3.0"
+
+"@babel/core@^7.11.6", "@babel/core@^7.12.3":
version "7.20.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92"
integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==
@@ -763,6 +784,15 @@
"@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
+"@babel/generator@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95"
+ integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==
+ dependencies:
+ "@babel/types" "^7.20.5"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ jsesc "^2.5.1"
+
"@babel/helper-annotate-as-pure@^7.16.0", "@babel/helper-annotate-as-pure@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
@@ -788,7 +818,7 @@
browserslist "^4.21.3"
semver "^6.3.0"
-"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2":
+"@babel/helper-create-class-features-plugin@^7.18.6":
version "7.20.2"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz#3c08a5b5417c7f07b5cf3dfb6dc79cbec682e8c2"
integrity sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==
@@ -801,6 +831,19 @@
"@babel/helper-replace-supers" "^7.19.1"
"@babel/helper-split-export-declaration" "^7.18.6"
+"@babel/helper-create-class-features-plugin@^7.20.2", "@babel/helper-create-class-features-plugin@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz#327154eedfb12e977baa4ecc72e5806720a85a06"
+ integrity sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-member-expression-to-functions" "^7.18.9"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/helper-replace-supers" "^7.19.1"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+
"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0":
version "7.19.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
@@ -964,6 +1007,15 @@
"@babel/traverse" "^7.20.1"
"@babel/types" "^7.20.0"
+"@babel/helpers@^7.20.5":
+ version "7.20.6"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763"
+ integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==
+ dependencies:
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.20.5"
+ "@babel/types" "^7.20.5"
+
"@babel/highlight@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
@@ -978,6 +1030,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2"
integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==
+"@babel/parser@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8"
+ integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==
+
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
@@ -1022,11 +1079,11 @@
"@babel/plugin-syntax-class-static-block" "^7.14.5"
"@babel/plugin-proposal-decorators@^7.16.4":
- version "7.20.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.2.tgz#1c6c32b2a44b154ebeec2bb534f9eaebdb541fb6"
- integrity sha512-nkBH96IBmgKnbHQ5gXFrcmez+Z9S2EIDKDQGp005ROqBigc88Tky4rzCnlP/lnlj245dCEQl4/YyV0V1kYh5dw==
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz#28ba1a0e5044664a512967a19407d7fc26925394"
+ integrity sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.20.2"
+ "@babel/helper-create-class-features-plugin" "^7.20.5"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-replace-supers" "^7.19.1"
"@babel/helper-split-export-declaration" "^7.18.6"
@@ -1714,14 +1771,21 @@
"@babel/plugin-transform-typescript" "^7.18.6"
"@babel/runtime-corejs3@^7.10.2":
- version "7.20.1"
- resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz#d0775a49bb5fba77e42cbb7276c9955c7b05af8d"
- integrity sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==
+ version "7.20.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz#63dae945963539ab0ad578efbf3eff271e7067ae"
+ integrity sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==
dependencies:
core-js-pure "^3.25.1"
- regenerator-runtime "^0.13.10"
+ regenerator-runtime "^0.13.11"
+
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.9.2":
+ version "7.20.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3"
+ integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
+ dependencies:
+ regenerator-runtime "^0.13.11"
-"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.10.4", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4":
version "7.20.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9"
integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==
@@ -1753,7 +1817,23 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+"@babel/traverse@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133"
+ integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.20.5"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.20.5"
+ "@babel/types" "^7.20.5"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
+"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
version "7.20.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842"
integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==
@@ -1762,6 +1842,15 @@
"@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
+"@babel/types@^7.12.6", "@babel/types@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84"
+ integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==
+ dependencies:
+ "@babel/helper-string-parser" "^7.19.4"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -2001,7 +2090,7 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4"
integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==
-"@csstools/postcss-cascade-layers@^1.1.0":
+"@csstools/postcss-cascade-layers@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad"
integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==
@@ -4547,9 +4636,9 @@
esquery "^1.0.1"
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
- version "0.5.9"
- resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.9.tgz#35aae6624a6270ca7ad755800b7eec417fa6f830"
- integrity sha512-7QV4cqUwhkDIHpMAZ9mestSJ2DMIotVTbOUwbiudhjCRTAWWKIaBecELiEM2LT3AHFeOAaHIcFu4dbXjX+9GBA==
+ version "0.5.10"
+ resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
+ integrity sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==
dependencies:
ansi-html-community "^0.0.8"
common-path-prefix "^3.0.0"
@@ -4557,7 +4646,7 @@
error-stack-parser "^2.0.6"
find-up "^5.0.0"
html-entities "^2.1.0"
- loader-utils "^2.0.3"
+ loader-utils "^2.0.4"
schema-utils "^3.0.0"
source-map "^0.7.3"
@@ -4844,9 +4933,10 @@
integrity sha512-PuxRlyTlycXrTU11B22XcCz1PUU7p5krXxnb+ztPkgR3fAMP3ubENgoUyLllUJXxx2O/Jpne+0P9HIro+vilPg==
"@spruceid/ssx@file:packages/ssx-sdk":
- version "0.1.1"
+ version "1.0.0"
dependencies:
"@metamask/detect-provider" "^1.2.0"
+ "@spruceid/ssx-core" "*"
"@spruceid/ssx-gnosis-extension" "*"
"@spruceid/ssx-sdk-wasm" "0.1.2"
"@types/lodash.merge" "^4.6.7"
@@ -5172,13 +5262,20 @@
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
version "7.18.2"
resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309"
integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==
dependencies:
"@babel/types" "^7.3.0"
+"@types/babel__traverse@^7.0.4":
+ version "7.18.3"
+ resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d"
+ integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==
+ dependencies:
+ "@babel/types" "^7.3.0"
+
"@types/bn.js@^4.11.3":
version "4.11.6"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
@@ -5357,9 +5454,9 @@
"@types/istanbul-lib-report" "*"
"@types/jest@*":
- version "29.2.2"
- resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.2.tgz#874e7dc6702fa6a3fe6107792aa98636dcc480b4"
- integrity sha512-og1wAmdxKoS71K2ZwSVqWPX6OVn3ihZ6ZT2qvZvZQm90lJVDyXIjYcu4Khx2CNIeaFv12rOU/YObOsI3VOkzog==
+ version "29.2.3"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.3.tgz#f5fd88e43e5a9e4221ca361e23790d48fcf0a211"
+ integrity sha512-6XwoEbmatfyoCjWRX7z0fKMmgYKe9+/HrviJ5k0X/tjJWHGAezZOfYaxqQKuzG/TvQyr+ktjm4jgbk0s4/oF2w==
dependencies:
expect "^29.0.0"
pretty-format "^29.0.0"
@@ -5522,9 +5619,9 @@
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
"@types/react-dom@^18.0.0":
- version "18.0.8"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.8.tgz#d2606d855186cd42cc1b11e63a71c39525441685"
- integrity sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw==
+ version "18.0.9"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504"
+ integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==
dependencies:
"@types/react" "*"
@@ -5677,7 +5774,7 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@^5.23.0", "@typescript-eslint/eslint-plugin@^5.27.0", "@typescript-eslint/eslint-plugin@^5.31.0", "@typescript-eslint/eslint-plugin@^5.5.0":
+"@typescript-eslint/eslint-plugin@^5.23.0", "@typescript-eslint/eslint-plugin@^5.27.0", "@typescript-eslint/eslint-plugin@^5.31.0":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz#696b9cc21dfd4749c1c8ad1307f76a36a00aa0e3"
integrity sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==
@@ -5692,14 +5789,29 @@
semver "^7.3.7"
tsutils "^3.21.0"
+"@typescript-eslint/eslint-plugin@^5.5.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz#ffa505cf961d4844d38cfa19dcec4973a6039e41"
+ integrity sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.45.0"
+ "@typescript-eslint/type-utils" "5.45.0"
+ "@typescript-eslint/utils" "5.45.0"
+ debug "^4.3.4"
+ ignore "^5.2.0"
+ natural-compare-lite "^1.4.0"
+ regexpp "^3.2.0"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
"@typescript-eslint/experimental-utils@^5.0.0":
- version "5.42.1"
- resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.42.1.tgz#755695d8f1b45dff7b5626cb48f33542227a3471"
- integrity sha512-qona75z2MLpeZADEuCet5Pwvh1g/0cWScEEDy43chuUPc4klgDiwz5hLFk5dHcjFEETSYQHRPYiiHKW24EMPjw==
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.45.0.tgz#b59fea61a855cb2b1fdbd0fb45934a844f4bf870"
+ integrity sha512-DnRQg5+3uHHt/gaifTjwg9OKbg9/TWehfJzYHQIDJboPEbF897BKDE/qoqMhW7nf0jWRV1mwVXTaUvtB1/9Gwg==
dependencies:
- "@typescript-eslint/utils" "5.42.1"
+ "@typescript-eslint/utils" "5.45.0"
-"@typescript-eslint/parser@^5.23.0", "@typescript-eslint/parser@^5.27.0", "@typescript-eslint/parser@^5.31.0", "@typescript-eslint/parser@^5.5.0":
+"@typescript-eslint/parser@^5.23.0", "@typescript-eslint/parser@^5.27.0", "@typescript-eslint/parser@^5.31.0":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.42.1.tgz#3e66156f2f74b11690b45950d8f5f28a62751d35"
integrity sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==
@@ -5709,6 +5821,16 @@
"@typescript-eslint/typescript-estree" "5.42.1"
debug "^4.3.4"
+"@typescript-eslint/parser@^5.5.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.0.tgz#b18a5f6b3cf1c2b3e399e9d2df4be40d6b0ddd0e"
+ integrity sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.45.0"
+ "@typescript-eslint/types" "5.45.0"
+ "@typescript-eslint/typescript-estree" "5.45.0"
+ debug "^4.3.4"
+
"@typescript-eslint/scope-manager@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz#05e5e1351485637d466464237e5259b49f609b18"
@@ -5717,6 +5839,14 @@
"@typescript-eslint/types" "5.42.1"
"@typescript-eslint/visitor-keys" "5.42.1"
+"@typescript-eslint/scope-manager@5.45.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz#7a4ac1bfa9544bff3f620ab85947945938319a96"
+ integrity sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==
+ dependencies:
+ "@typescript-eslint/types" "5.45.0"
+ "@typescript-eslint/visitor-keys" "5.45.0"
+
"@typescript-eslint/type-utils@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz#21328feb2d4b193c5852b35aabd241ccc1449daa"
@@ -5727,11 +5857,26 @@
debug "^4.3.4"
tsutils "^3.21.0"
+"@typescript-eslint/type-utils@5.45.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz#aefbc954c40878fcebeabfb77d20d84a3da3a8b2"
+ integrity sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==
+ dependencies:
+ "@typescript-eslint/typescript-estree" "5.45.0"
+ "@typescript-eslint/utils" "5.45.0"
+ debug "^4.3.4"
+ tsutils "^3.21.0"
+
"@typescript-eslint/types@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.42.1.tgz#0d4283c30e9b70d2aa2391c36294413de9106df2"
integrity sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==
+"@typescript-eslint/types@5.45.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.0.tgz#794760b9037ee4154c09549ef5a96599621109c5"
+ integrity sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==
+
"@typescript-eslint/typescript-estree@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz#f9a223ecb547a781d37e07a5ac6ba9ff681eaef0"
@@ -5745,7 +5890,20 @@
semver "^7.3.7"
tsutils "^3.21.0"
-"@typescript-eslint/utils@5.42.1", "@typescript-eslint/utils@^5.13.0":
+"@typescript-eslint/typescript-estree@5.45.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz#f70a0d646d7f38c0dfd6936a5e171a77f1e5291d"
+ integrity sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==
+ dependencies:
+ "@typescript-eslint/types" "5.45.0"
+ "@typescript-eslint/visitor-keys" "5.45.0"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
+"@typescript-eslint/utils@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.42.1.tgz#2789b1cd990f0c07aaa3e462dbe0f18d736d5071"
integrity sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==
@@ -5759,6 +5917,20 @@
eslint-utils "^3.0.0"
semver "^7.3.7"
+"@typescript-eslint/utils@5.45.0", "@typescript-eslint/utils@^5.13.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.0.tgz#9cca2996eee1b8615485a6918a5c763629c7acf5"
+ integrity sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ "@types/semver" "^7.3.12"
+ "@typescript-eslint/scope-manager" "5.45.0"
+ "@typescript-eslint/types" "5.45.0"
+ "@typescript-eslint/typescript-estree" "5.45.0"
+ eslint-scope "^5.1.1"
+ eslint-utils "^3.0.0"
+ semver "^7.3.7"
+
"@typescript-eslint/visitor-keys@5.42.1":
version "5.42.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz#df10839adf6605e1cdb79174cf21e46df9be4872"
@@ -5767,6 +5939,14 @@
"@typescript-eslint/types" "5.42.1"
eslint-visitor-keys "^3.3.0"
+"@typescript-eslint/visitor-keys@5.45.0":
+ version "5.45.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz#e0d160e9e7fdb7f8da697a5b78e7a14a22a70528"
+ integrity sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==
+ dependencies:
+ "@typescript-eslint/types" "5.45.0"
+ eslint-visitor-keys "^3.3.0"
+
"@wagmi/core@^0.6.12":
version "0.6.12"
resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-0.6.12.tgz#19d35424840a8c9f5396869e24464e2137ea8fc2"
@@ -6352,7 +6532,7 @@ ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@~6.12.6:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ajv@^8.0.0, ajv@^8.11.0, ajv@^8.6.0, ajv@^8.8.0:
+ajv@^8.0.0, ajv@^8.11.0, ajv@^8.8.0:
version "8.11.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
@@ -6362,6 +6542,16 @@ ajv@^8.0.0, ajv@^8.11.0, ajv@^8.6.0, ajv@^8.8.0:
require-from-string "^2.0.2"
uri-js "^4.2.2"
+ajv@^8.6.0:
+ version "8.11.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78"
+ integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+ uri-js "^4.2.2"
+
ansi-align@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
@@ -6572,7 +6762,7 @@ array-ify@^1.0.0:
resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==
-array-includes@^3.1.4, array-includes@^3.1.5:
+array-includes@^3.1.4, array-includes@^3.1.5, array-includes@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f"
integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==
@@ -6615,7 +6805,7 @@ array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5:
es-abstract "^1.20.4"
es-shim-unscopables "^1.0.0"
-array.prototype.flatmap@^1.3.0:
+array.prototype.flatmap@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183"
integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==
@@ -6636,6 +6826,17 @@ array.prototype.reduce@^1.0.5:
es-array-method-boxes-properly "^1.0.0"
is-string "^1.0.7"
+array.prototype.tosorted@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532"
+ integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
+ get-intrinsic "^1.1.3"
+
arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@@ -6739,7 +6940,7 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
-autoprefixer@^10.4.11:
+autoprefixer@^10.4.13:
version "10.4.13"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8"
integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==
@@ -6783,9 +6984,9 @@ aws4@^1.8.0:
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
axe-core@^4.4.3:
- version "4.5.1"
- resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.5.1.tgz#04d561c11b6d76d096d34e9d14ba2c294fb20cdc"
- integrity sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==
+ version "4.5.2"
+ resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.5.2.tgz#823fdf491ff717ac3c58a52631d4206930c1d9f7"
+ integrity sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==
axios@^0.21.0, axios@^0.21.1:
version "0.21.4"
@@ -6802,7 +7003,7 @@ axios@^0.27.2:
follow-redirects "^1.14.9"
form-data "^4.0.0"
-axios@^1.0.0, axios@^1.1.3:
+axios@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.3.tgz#8274250dada2edf53814ed7db644b9c2866c1e35"
integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==
@@ -7635,7 +7836,12 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426:
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001426:
+ version "1.0.30001434"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz#ec1ec1cfb0a93a34a0600d37903853030520a4e5"
+ integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==
+
+caniuse-lite@^1.0.30001400:
version "1.0.30001431"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz#e7c59bd1bc518fae03a4656be442ce6c4887a795"
integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==
@@ -7714,9 +7920,9 @@ chardet@^0.7.0:
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
check-types@^11.1.1:
- version "11.1.2"
- resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f"
- integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==
+ version "11.2.2"
+ resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4"
+ integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==
checkpoint-store@^1.1.0:
version "1.1.0"
@@ -8414,14 +8620,14 @@ core-js-compat@^3.25.1:
browserslist "^4.21.4"
core-js-pure@^3.23.3, core-js-pure@^3.25.1:
- version "3.26.0"
- resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.26.0.tgz#7ad8a5dd7d910756f3124374b50026e23265ca9a"
- integrity sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==
+ version "3.26.1"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.26.1.tgz#653f4d7130c427820dcecd3168b594e8bb095a33"
+ integrity sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==
core-js@^3.19.2:
- version "3.26.0"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.0.tgz#a516db0ed0811be10eac5d94f3b8463d03faccfe"
- integrity sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==
+ version "3.26.1"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.1.tgz#7a9816dabd9ee846c1c0fe0e8fcad68f3709134e"
+ integrity sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==
core-util-is@1.0.2:
version "1.0.2"
@@ -8625,18 +8831,18 @@ css-has-pseudo@^3.0.4:
postcss-selector-parser "^6.0.9"
css-loader@^6.5.1:
- version "6.7.1"
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e"
- integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==
+ version "6.7.2"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.2.tgz#26bc22401b5921686a10fbeba75d124228302304"
+ integrity sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==
dependencies:
icss-utils "^5.1.0"
- postcss "^8.4.7"
+ postcss "^8.4.18"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0"
postcss-value-parser "^4.2.0"
- semver "^7.3.5"
+ semver "^7.3.8"
css-minimizer-webpack-plugin@^3.2.0:
version "3.4.1"
@@ -8736,7 +8942,7 @@ css.escape@^1.5.1:
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==
-cssdb@^7.0.1:
+cssdb@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.1.0.tgz#574f97235a83eb753a29f0b1f2cbacac0d628bb8"
integrity sha512-Sd99PrFgx28ez4GHu8yoQIufc/70h9oYowDf4EjeIKi8mac9whxRjhM3IaMr6EllP6KKKWtJrMfN6C7T9tIWvQ==
@@ -10162,24 +10368,25 @@ eslint-plugin-react-hooks@^4.3.0:
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
eslint-plugin-react@^7.27.1:
- version "7.31.10"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz#6782c2c7fe91c09e715d536067644bbb9491419a"
- integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==
+ version "7.31.11"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz#011521d2b16dcf95795df688a4770b4eaab364c8"
+ integrity sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==
dependencies:
- array-includes "^3.1.5"
- array.prototype.flatmap "^1.3.0"
+ array-includes "^3.1.6"
+ array.prototype.flatmap "^1.3.1"
+ array.prototype.tosorted "^1.1.1"
doctrine "^2.1.0"
estraverse "^5.3.0"
jsx-ast-utils "^2.4.1 || ^3.0.0"
minimatch "^3.1.2"
- object.entries "^1.1.5"
- object.fromentries "^2.0.5"
- object.hasown "^1.1.1"
- object.values "^1.1.5"
+ object.entries "^1.1.6"
+ object.fromentries "^2.0.6"
+ object.hasown "^1.1.2"
+ object.values "^1.1.6"
prop-types "^15.8.1"
resolve "^2.0.0-next.3"
semver "^6.3.0"
- string.prototype.matchall "^4.0.7"
+ string.prototype.matchall "^4.0.8"
eslint-plugin-testing-library@^5.0.1:
version "5.9.1"
@@ -10232,7 +10439,7 @@ eslint-webpack-plugin@^3.1.1:
normalize-path "^3.0.0"
schema-utils "^4.0.0"
-eslint@^8.15.0, eslint@^8.3.0:
+eslint@^8.15.0:
version "8.27.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.27.0.tgz#d547e2f7239994ad1faa4bb5d84e5d809db7cf64"
integrity sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==
@@ -10321,6 +10528,51 @@ eslint@^8.16.0, eslint@^8.20.0:
strip-json-comments "^3.1.0"
text-table "^0.2.0"
+eslint@^8.28.0, eslint@^8.3.0:
+ version "8.28.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.28.0.tgz#81a680732634677cc890134bcdd9fdfea8e63d6e"
+ integrity sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==
+ dependencies:
+ "@eslint/eslintrc" "^1.3.3"
+ "@humanwhocodes/config-array" "^0.11.6"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "@nodelib/fs.walk" "^1.2.8"
+ ajv "^6.10.0"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.3.2"
+ doctrine "^3.0.0"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^7.1.1"
+ eslint-utils "^3.0.0"
+ eslint-visitor-keys "^3.3.0"
+ espree "^9.4.0"
+ esquery "^1.4.0"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ find-up "^5.0.0"
+ glob-parent "^6.0.2"
+ globals "^13.15.0"
+ grapheme-splitter "^1.0.4"
+ ignore "^5.2.0"
+ import-fresh "^3.0.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ is-path-inside "^3.0.3"
+ js-sdsl "^4.1.4"
+ js-yaml "^4.1.0"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
+ natural-compare "^1.4.0"
+ optionator "^0.9.1"
+ regexpp "^3.2.0"
+ strip-ansi "^6.0.1"
+ strip-json-comments "^3.1.0"
+ text-table "^0.2.0"
+
esniff@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-1.1.0.tgz#c66849229f91464dede2e0d40201ed6abf65f2ac"
@@ -14627,19 +14879,19 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
-loader-utils@^2.0.0, loader-utils@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.3.tgz#d4b15b8504c63d1fc3f2ade52d41bc8459d6ede1"
- integrity sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==
+loader-utils@^2.0.0, loader-utils@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
+ integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
json5 "^2.1.2"
loader-utils@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f"
- integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576"
+ integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==
locate-path@^2.0.0:
version "2.0.0"
@@ -15132,9 +15384,9 @@ memdown@^1.0.0:
safe-buffer "~5.1.1"
memfs@^3.1.2, memfs@^3.4.3:
- version "3.4.10"
- resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.10.tgz#4cdff7cfd21351a85e11b08aa276ebf100210a4d"
- integrity sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ==
+ version "3.4.12"
+ resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.12.tgz#d00f8ad8dab132dc277c659dc85bfd14b07d03bd"
+ integrity sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==
dependencies:
fs-monkey "^1.0.3"
@@ -15302,9 +15554,9 @@ min-indent@^1.0.0:
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
mini-css-extract-plugin@^2.4.5:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e"
- integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.0.tgz#d7d9ba0c5b596d155e36e2b174082fc7f010dd64"
+ integrity sha512-auqtVo8KhTScMsba7MbijqZTfibbXiBNlPAQbsVt7enQfcDYLdgG57eGxMqwVU3mfeWANY4F1wUg+rMF+ycZgw==
dependencies:
schema-utils "^4.0.0"
@@ -16155,7 +16407,7 @@ object.assign@^4.1.2, object.assign@^4.1.3, object.assign@^4.1.4:
has-symbols "^1.0.3"
object-keys "^1.1.1"
-object.entries@^1.1.5:
+object.entries@^1.1.5, object.entries@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23"
integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==
@@ -16164,7 +16416,7 @@ object.entries@^1.1.5:
define-properties "^1.1.4"
es-abstract "^1.20.4"
-object.fromentries@^2.0.5:
+object.fromentries@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73"
integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==
@@ -16183,7 +16435,7 @@ object.getownpropertydescriptors@^2.1.0:
define-properties "^1.1.4"
es-abstract "^1.20.4"
-object.hasown@^1.1.1, object.hasown@^1.1.2:
+object.hasown@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92"
integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==
@@ -16198,7 +16450,7 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"
-object.values@^1.1.0, object.values@^1.1.5:
+object.values@^1.1.0, object.values@^1.1.5, object.values@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d"
integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==
@@ -16897,7 +17149,7 @@ postcss-custom-media@^8.0.2:
dependencies:
postcss-value-parser "^4.2.0"
-postcss-custom-properties@^12.1.9:
+postcss-custom-properties@^12.1.10:
version "12.1.10"
resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.10.tgz#624517179fd4cf50078a7a60f628d5782e7d4903"
integrity sha512-U3BHdgrYhCrwTVcByFHs9EOBoqcKq4Lf3kXwbTi4hhq0qWhl/pDWq2THbv/ICX/Fl9KqeHBb8OVrTf2OaYF07A==
@@ -17243,11 +17495,11 @@ postcss-place@^7.0.5:
postcss-value-parser "^4.2.0"
postcss-preset-env@^7.0.1:
- version "7.8.2"
- resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz#4c834d5cbd2e29df2abf59118947c456922b79ba"
- integrity sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz#2a50f5e612c3149cc7af75634e202a5b2ad4f1e2"
+ integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==
dependencies:
- "@csstools/postcss-cascade-layers" "^1.1.0"
+ "@csstools/postcss-cascade-layers" "^1.1.1"
"@csstools/postcss-color-function" "^1.1.1"
"@csstools/postcss-font-format-keywords" "^1.0.1"
"@csstools/postcss-hwb-function" "^1.0.2"
@@ -17261,19 +17513,19 @@ postcss-preset-env@^7.0.1:
"@csstools/postcss-text-decoration-shorthand" "^1.0.0"
"@csstools/postcss-trigonometric-functions" "^1.0.2"
"@csstools/postcss-unset-value" "^1.0.2"
- autoprefixer "^10.4.11"
- browserslist "^4.21.3"
+ autoprefixer "^10.4.13"
+ browserslist "^4.21.4"
css-blank-pseudo "^3.0.3"
css-has-pseudo "^3.0.4"
css-prefers-color-scheme "^6.0.3"
- cssdb "^7.0.1"
+ cssdb "^7.1.0"
postcss-attribute-case-insensitive "^5.0.2"
postcss-clamp "^4.1.0"
postcss-color-functional-notation "^4.2.4"
postcss-color-hex-alpha "^8.0.4"
postcss-color-rebeccapurple "^7.1.1"
postcss-custom-media "^8.0.2"
- postcss-custom-properties "^12.1.9"
+ postcss-custom-properties "^12.1.10"
postcss-custom-selectors "^6.0.3"
postcss-dir-pseudo-class "^6.0.5"
postcss-double-position-gradients "^3.1.2"
@@ -17332,9 +17584,9 @@ postcss-selector-not@^6.0.1:
postcss-selector-parser "^6.0.10"
postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9:
- version "6.0.10"
- resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
- integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
+ version "6.0.11"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc"
+ integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
@@ -17367,10 +17619,10 @@ postcss@^7.0.35:
picocolors "^0.2.1"
source-map "^0.6.1"
-postcss@^8.3.5, postcss@^8.4.18, postcss@^8.4.4, postcss@^8.4.7:
- version "8.4.18"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.18.tgz#6d50046ea7d3d66a85e0e782074e7203bc7fbca2"
- integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==
+postcss@^8.3.5, postcss@^8.4.18, postcss@^8.4.4:
+ version "8.4.19"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc"
+ integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
@@ -18150,11 +18402,16 @@ regenerate@^1.4.2:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
-regenerator-runtime@^0.13.10, regenerator-runtime@^0.13.9:
+regenerator-runtime@^0.13.10:
version "0.13.10"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"
integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==
+regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.9:
+ version "0.13.11"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
+ integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
+
regenerator-transform@^0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537"
@@ -19517,7 +19774,7 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
-string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.7:
+string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3"
integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==
@@ -19847,9 +20104,9 @@ symbol-tree@^3.2.4:
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
tailwindcss@^3.0.2:
- version "3.2.3"
- resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.3.tgz#c5ee3cb95dae7a80592d43a460d277915c7b2938"
- integrity sha512-Xt9D4PK4zuuQCEB8bwK9JUCKmTgUwyac/6b0/42Vqhgl6YJkep+Wf5wq+5uXYfmrupdAD0YY2NY1hyZp1HjRrg==
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250"
+ integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==
dependencies:
arg "^5.0.2"
chokidar "^3.5.3"
@@ -19979,7 +20236,17 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5:
serialize-javascript "^6.0.0"
terser "^5.14.1"
-terser@^5.0.0, terser@^5.10.0, terser@^5.14.1:
+terser@^5.0.0, terser@^5.10.0:
+ version "5.16.0"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.0.tgz#29362c6f5506e71545c73b069ccd199bb28f7f54"
+ integrity sha512-KjTV81QKStSfwbNiwlBXfcgMcOloyuRdb62/iLFPGBcVNF4EXjhdYBhYHmbJpiBrVxZhDvltE11j+LBQUxEEJg==
+ dependencies:
+ "@jridgewell/source-map" "^0.3.2"
+ acorn "^8.5.0"
+ commander "^2.20.0"
+ source-map-support "~0.5.20"
+
+terser@^5.14.1:
version "5.15.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c"
integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==