From 3db077105a5f7b4b843e55ac649faf500b9227e5 Mon Sep 17 00:00:00 2001 From: zaidarain1 Date: Thu, 8 Aug 2024 15:57:19 +1000 Subject: [PATCH 01/29] feat: [DX-3086] Update TSConfig and fix ESLint for SDK Packages (#2082) --- .eslintrc | 4 +- package.json | 2 +- .../sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/blockchain-data/sdk/src/index.ts | 6 +- packages/blockchain-data/sdk/tsconfig.json | 14 +-- packages/checkout/sdk-sample-app/.env | 1 + packages/checkout/sdk-sample-app/.gitignore | 1 + .../checkout/sdk/{.eslintrc => .eslintrc.cjs} | 6 +- packages/checkout/sdk/src/index.ts | 17 ++- packages/checkout/sdk/tsconfig.json | 14 +-- .../widgets-lib/{.eslintrc => .eslintrc.cjs} | 4 +- packages/checkout/widgets-lib/package.json | 1 + .../src/views/top-up/TopUpView.tsx | 3 +- packages/checkout/widgets-lib/tsconfig.json | 18 +-- packages/config/.eslintrc.cjs | 11 ++ packages/config/tsconfig.json | 14 +-- .../.eslintrc => game-bridge/.eslintrc.cjs} | 4 +- packages/game-bridge/tsconfig.json | 107 +----------------- packages/internal/.eslintrc | 9 +- packages/internal/bridge/sdk/.eslintrc | 4 +- packages/internal/bridge/sdk/tsconfig.json | 20 +--- packages/internal/cryptofiat/tsconfig.json | 14 +-- packages/internal/dex/sdk/tsconfig.json | 20 +--- packages/internal/factory/sdk/.eslintrc | 2 +- packages/internal/factory/sdk/tsconfig.json | 20 +--- .../.eslintrc.cjs} | 6 +- .../internal/generated-clients/src/index.ts | 6 +- .../internal/generated-clients/tsconfig.json | 14 +-- .../guardian/.eslintrc.cjs} | 7 +- packages/internal/guardian/tsconfig.json | 20 +--- .../metrics/.eslintrc.cjs} | 6 +- packages/internal/metrics/src/index.ts | 3 +- packages/internal/metrics/tsconfig.json | 107 +----------------- packages/internal/toolkit/package.json | 2 +- packages/internal/toolkit/tsconfig.json | 14 +-- .../sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/minting-backend/sdk/tsconfig.json | 14 +-- .../orderbook/{.eslintrc => .eslintrc.cjs} | 6 +- packages/orderbook/src/index.ts | 2 +- packages/orderbook/tsconfig.json | 14 +-- .../passport/sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/passport/sdk/package.json | 2 +- packages/passport/sdk/src/index.ts | 9 +- packages/passport/sdk/tsconfig.json | 16 +-- .../webhook/sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/webhook/sdk/src/index.ts | 4 +- packages/webhook/sdk/tsconfig.json | 14 +-- .../.eslintrc => x-client/.eslintrc.cjs} | 4 +- packages/x-client/src/index.ts | 4 +- packages/x-client/src/types/api.ts | 11 +- packages/x-client/tsconfig.json | 13 +-- .../x-provider/{.eslintrc => .eslintrc.cjs} | 4 +- packages/x-provider/package.json | 2 +- packages/x-provider/src/index.ts | 2 +- packages/x-provider/src/sample-app/.env | 1 + packages/x-provider/src/sample-app/.gitignore | 1 + packages/x-provider/tsconfig.json | 14 +-- sdk/{.eslintrc => .eslintrc.cjs} | 5 +- sdk/package.json | 2 +- sdk/tsconfig.json | 18 +-- tests/func-tests/zkevm/tsconfig.json | 11 ++ tsconfig.json => tsconfig.base.json | 7 +- yarn.lock | 20 +++- 63 files changed, 161 insertions(+), 556 deletions(-) rename packages/blockchain-data/sdk/{.eslintrc => .eslintrc.cjs} (79%) create mode 100644 packages/checkout/sdk-sample-app/.env rename packages/checkout/sdk/{.eslintrc => .eslintrc.cjs} (77%) rename packages/checkout/widgets-lib/{.eslintrc => .eslintrc.cjs} (97%) create mode 100644 packages/config/.eslintrc.cjs rename packages/{x-client/.eslintrc => game-bridge/.eslintrc.cjs} (72%) rename packages/internal/{metrics/.eslintrc => generated-clients/.eslintrc.cjs} (55%) rename packages/{checkout/sdk-sample-app/.eslintrc => internal/guardian/.eslintrc.cjs} (55%) rename packages/{game-bridge/.eslintrc => internal/metrics/.eslintrc.cjs} (55%) rename packages/minting-backend/sdk/{.eslintrc => .eslintrc.cjs} (79%) rename packages/orderbook/{.eslintrc => .eslintrc.cjs} (92%) rename packages/passport/sdk/{.eslintrc => .eslintrc.cjs} (90%) rename packages/webhook/sdk/{.eslintrc => .eslintrc.cjs} (79%) rename packages/{checkout/.eslintrc => x-client/.eslintrc.cjs} (72%) rename packages/x-provider/{.eslintrc => .eslintrc.cjs} (86%) create mode 100644 packages/x-provider/src/sample-app/.env rename sdk/{.eslintrc => .eslintrc.cjs} (75%) create mode 100644 tests/func-tests/zkevm/tsconfig.json rename tsconfig.json => tsconfig.base.json (80%) diff --git a/.eslintrc b/.eslintrc index dd819129f9..197e3b9049 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,9 @@ "node_modules/", "dist/", "**sample-app**/", - "**playground**/" + "**playground**/", + "*.cjs", + "tests/func-tests/" ], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/package.json b/package.json index 166433557e..330eda0a33 100644 --- a/package.json +++ b/package.json @@ -106,4 +106,4 @@ "tests/**" ] } -} \ No newline at end of file +} diff --git a/packages/blockchain-data/sdk/.eslintrc b/packages/blockchain-data/sdk/.eslintrc.cjs similarity index 79% rename from packages/blockchain-data/sdk/.eslintrc rename to packages/blockchain-data/sdk/.eslintrc.cjs index f77729693e..3193df85c8 100644 --- a/packages/blockchain-data/sdk/.eslintrc +++ b/packages/blockchain-data/sdk/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/comma-dangle": "off" diff --git a/packages/blockchain-data/sdk/src/index.ts b/packages/blockchain-data/sdk/src/index.ts index e86427ab7c..c41275b82d 100644 --- a/packages/blockchain-data/sdk/src/index.ts +++ b/packages/blockchain-data/sdk/src/index.ts @@ -14,7 +14,9 @@ type ActivityType = mr.ActivityType; export { Types, APIError, - BlockchainData, + BlockchainData +}; +export type { BlockchainDataModuleConfiguration, - ActivityType, + ActivityType }; diff --git a/packages/blockchain-data/sdk/tsconfig.json b/packages/blockchain-data/sdk/tsconfig.json index 56c27e347a..e43a0c438f 100644 --- a/packages/blockchain-data/sdk/tsconfig.json +++ b/packages/blockchain-data/sdk/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/checkout/sdk-sample-app/.env b/packages/checkout/sdk-sample-app/.env new file mode 100644 index 0000000000..02269f00d9 --- /dev/null +++ b/packages/checkout/sdk-sample-app/.env @@ -0,0 +1 @@ +DISABLE_ESLINT_PLUGIN=true diff --git a/packages/checkout/sdk-sample-app/.gitignore b/packages/checkout/sdk-sample-app/.gitignore index 4d29575de8..e72ae06a01 100644 --- a/packages/checkout/sdk-sample-app/.gitignore +++ b/packages/checkout/sdk-sample-app/.gitignore @@ -17,6 +17,7 @@ .env.development.local .env.test.local .env.production.local +!.env npm-debug.log* yarn-debug.log* diff --git a/packages/checkout/sdk/.eslintrc b/packages/checkout/sdk/.eslintrc.cjs similarity index 77% rename from packages/checkout/sdk/.eslintrc rename to packages/checkout/sdk/.eslintrc.cjs index b4d4cad6cc..62a8693da0 100644 --- a/packages/checkout/sdk/.eslintrc +++ b/packages/checkout/sdk/.eslintrc.cjs @@ -1,10 +1,10 @@ -{ - "extends": ["../.eslintrc"], +module.exports = { + "extends": ["../../../.eslintrc"], "ignorePatterns": ["jest.config.*", "rollup.config.*"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "prefer-promise-reject-errors": "off", diff --git a/packages/checkout/sdk/src/index.ts b/packages/checkout/sdk/src/index.ts index 742b2b1f52..7b6a01091d 100644 --- a/packages/checkout/sdk/src/index.ts +++ b/packages/checkout/sdk/src/index.ts @@ -22,11 +22,7 @@ export { ChainId, ChainName, ChainSlug, - CheckoutStatus, - EIP1193Provider, - EIP6963ProviderInfo, - EIP6963ProviderDetail, - ExchangeType, + CheckoutStatus, ExchangeType, FeeType, FundingStepType, GasEstimateType, @@ -40,6 +36,11 @@ export { WalletProviderName, WalletProviderRdns, } from './types'; +export type { + EIP1193Provider, + EIP6963ProviderInfo, + EIP6963ProviderDetail, +} from './types'; export type { AllowedNetworkConfig, @@ -144,11 +145,9 @@ export type { } from './types'; export { - PostMessageHandler, - PostMessageHandlerConfiguration, - PostMessageHandlerEventType, - PostMessageData, + PostMessageHandler, PostMessageHandlerEventType, } from './postMessageHandler'; +export type { PostMessageHandlerConfiguration, PostMessageData } from './postMessageHandler'; export { isAddressSanctioned } from './sanctions'; diff --git a/packages/checkout/sdk/tsconfig.json b/packages/checkout/sdk/tsconfig.json index 8c65238d9f..dfef981dd2 100644 --- a/packages/checkout/sdk/tsconfig.json +++ b/packages/checkout/sdk/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true, }, "include": ["src", "test/__mocks__/window.ts"], "exclude": ["node_modules", "dist", "test"] diff --git a/packages/checkout/widgets-lib/.eslintrc b/packages/checkout/widgets-lib/.eslintrc.cjs similarity index 97% rename from packages/checkout/widgets-lib/.eslintrc rename to packages/checkout/widgets-lib/.eslintrc.cjs index 5214d4447b..96bdd2ff19 100644 --- a/packages/checkout/widgets-lib/.eslintrc +++ b/packages/checkout/widgets-lib/.eslintrc.cjs @@ -1,10 +1,10 @@ -{ +module.exports = { "extends": ["../../../.eslintrc"], "ignorePatterns": ["jest.config.*", "rollup.config.*"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/naming-convention": [ diff --git a/packages/checkout/widgets-lib/package.json b/packages/checkout/widgets-lib/package.json index 629ab890e2..1a77dbf39d 100644 --- a/packages/checkout/widgets-lib/package.json +++ b/packages/checkout/widgets-lib/package.json @@ -36,6 +36,7 @@ "i18next-browser-languagedetector": "^7.2.0", "os-browserify": "^0.3.0", "pako": "^2.1.0", + "pino-pretty": "^11.2.2", "react-i18next": "^13.5.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", diff --git a/packages/checkout/widgets-lib/src/views/top-up/TopUpView.tsx b/packages/checkout/widgets-lib/src/views/top-up/TopUpView.tsx index 1467e3c73c..38710b0f13 100644 --- a/packages/checkout/widgets-lib/src/views/top-up/TopUpView.tsx +++ b/packages/checkout/widgets-lib/src/views/top-up/TopUpView.tsx @@ -12,7 +12,6 @@ import { import { Environment } from '@imtbl/config'; import { Web3Provider } from '@ethersproject/providers'; import { useTranslation } from 'react-i18next'; -import { $Dictionary } from 'i18next/typescript/helpers'; import { UserJourney, useAnalytics, @@ -40,6 +39,8 @@ import { OnRampWidgetViews } from '../../context/view-context/OnRampViewContextT import { EventTargetContext } from '../../context/event-target-context/EventTargetContext'; import { TopUpMenuItem, TopUpMenuItemProps } from './TopUpMenuItem'; +type $Dictionary = { [key: string]: T }; + interface TopUpViewProps { widgetEvent: IMTBLWidgetEvents; checkout?: Checkout; diff --git a/packages/checkout/widgets-lib/tsconfig.json b/packages/checkout/widgets-lib/tsconfig.json index b7238c9141..fb0ee09b32 100644 --- a/packages/checkout/widgets-lib/tsconfig.json +++ b/packages/checkout/widgets-lib/tsconfig.json @@ -1,26 +1,16 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "target": "es2022", "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true, "jsx": "react-jsx", "noImplicitAny": false, "jsxImportSource": "@emotion/react", - "experimentalDecorators": true + "experimentalDecorators": true, + "skipLibCheck": true }, - "include": ["src", "babel.config.js"], + "include": ["src"], "exclude": ["node_modules", "dist"] } diff --git a/packages/config/.eslintrc.cjs b/packages/config/.eslintrc.cjs new file mode 100644 index 0000000000..11b2a3d1ba --- /dev/null +++ b/packages/config/.eslintrc.cjs @@ -0,0 +1,11 @@ +module.exports = { + "extends": ["../../.eslintrc"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json", + "tsconfigRootDir": __dirname + }, + "rules": { + "@typescript-eslint/comma-dangle": "off" + } +} diff --git a/packages/config/tsconfig.json b/packages/config/tsconfig.json index 56c27e347a..ee6d658245 100644 --- a/packages/config/tsconfig.json +++ b/packages/config/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/x-client/.eslintrc b/packages/game-bridge/.eslintrc.cjs similarity index 72% rename from packages/x-client/.eslintrc rename to packages/game-bridge/.eslintrc.cjs index f90c594b06..8b8a821f7e 100644 --- a/packages/x-client/.eslintrc +++ b/packages/game-bridge/.eslintrc.cjs @@ -1,8 +1,8 @@ -{ +module.exports = { "extends": ["../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname } } diff --git a/packages/game-bridge/tsconfig.json b/packages/game-bridge/tsconfig.json index fc204f35c4..89d5c7b53d 100644 --- a/packages/game-bridge/tsconfig.json +++ b/packages/game-bridge/tsconfig.json @@ -1,109 +1,8 @@ { + "extends": "../../tsconfig.base.json", "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": "es2022", /* 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": "esnext", /* Specify what module code is generated. */ - // "rootDir": "./src", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - "rootDirs": ["src"], /* 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": false, /* 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. */ - - /* Advanced */ - // "noEmit": true, - // "allowJs": false, - // "allowSyntheticDefaultImports": true, - // "resolveJsonModule": true, + "outDir": "./dist", + "rootDirs": ["src"], }, "include": ["src"], "exclude": ["dist", "jest.config.js", "node_modules"] diff --git a/packages/internal/.eslintrc b/packages/internal/.eslintrc index a6393a1ed1..589b3bc659 100644 --- a/packages/internal/.eslintrc +++ b/packages/internal/.eslintrc @@ -1,9 +1,4 @@ { "ignorePatterns": ["**sample-app**/"], - "extends": ["../../.eslintrc"], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "./tsconfig.json", - "tsconfigRootDir": "." - } -} + "extends": ["../../.eslintrc"] +} \ No newline at end of file diff --git a/packages/internal/bridge/sdk/.eslintrc b/packages/internal/bridge/sdk/.eslintrc index 9c72b59200..3dae7773ec 100644 --- a/packages/internal/bridge/sdk/.eslintrc +++ b/packages/internal/bridge/sdk/.eslintrc @@ -1,7 +1,5 @@ { - "extends": [ - "../../../../.eslintrc" - ], + "extends": ["../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", diff --git a/packages/internal/bridge/sdk/tsconfig.json b/packages/internal/bridge/sdk/tsconfig.json index 66365daa07..c13a94c467 100644 --- a/packages/internal/bridge/sdk/tsconfig.json +++ b/packages/internal/bridge/sdk/tsconfig.json @@ -1,24 +1,8 @@ { + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "rootDirs": [ - "src" - ], - "target": "es2022", - "module": "es2022", - "moduleResolution": "node", - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "noFallthroughCasesInSwitch": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true, + "rootDirs": ["src"], }, "include": [ "src" diff --git a/packages/internal/cryptofiat/tsconfig.json b/packages/internal/cryptofiat/tsconfig.json index 56c27e347a..e43a0c438f 100644 --- a/packages/internal/cryptofiat/tsconfig.json +++ b/packages/internal/cryptofiat/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/internal/dex/sdk/tsconfig.json b/packages/internal/dex/sdk/tsconfig.json index 7a7f818705..18cf2ecd20 100644 --- a/packages/internal/dex/sdk/tsconfig.json +++ b/packages/internal/dex/sdk/tsconfig.json @@ -1,24 +1,8 @@ { + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "rootDirs": [ - "src" - ], - "target": "es2022", - "module": "es2022", - "moduleResolution": "node", - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "noFallthroughCasesInSwitch": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true + "rootDirs": ["src"], }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/internal/factory/sdk/.eslintrc b/packages/internal/factory/sdk/.eslintrc index 9c72b59200..e3881a722e 100644 --- a/packages/internal/factory/sdk/.eslintrc +++ b/packages/internal/factory/sdk/.eslintrc @@ -1,6 +1,6 @@ { "extends": [ - "../../../../.eslintrc" + "../../.eslintrc" ], "parser": "@typescript-eslint/parser", "parserOptions": { diff --git a/packages/internal/factory/sdk/tsconfig.json b/packages/internal/factory/sdk/tsconfig.json index 66365daa07..c13a94c467 100644 --- a/packages/internal/factory/sdk/tsconfig.json +++ b/packages/internal/factory/sdk/tsconfig.json @@ -1,24 +1,8 @@ { + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "rootDirs": [ - "src" - ], - "target": "es2022", - "module": "es2022", - "moduleResolution": "node", - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "noFallthroughCasesInSwitch": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true, + "rootDirs": ["src"], }, "include": [ "src" diff --git a/packages/internal/metrics/.eslintrc b/packages/internal/generated-clients/.eslintrc.cjs similarity index 55% rename from packages/internal/metrics/.eslintrc rename to packages/internal/generated-clients/.eslintrc.cjs index 9b6c8a5aef..cc10d70796 100644 --- a/packages/internal/metrics/.eslintrc +++ b/packages/internal/generated-clients/.eslintrc.cjs @@ -1,8 +1,8 @@ -{ - "extends": ["../../../.eslintrc"], +module.exports = { + "extends": ["../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname } } diff --git a/packages/internal/generated-clients/src/index.ts b/packages/internal/generated-clients/src/index.ts index 03e1bcb449..949fc689d4 100644 --- a/packages/internal/generated-clients/src/index.ts +++ b/packages/internal/generated-clients/src/index.ts @@ -4,9 +4,7 @@ export * as BlockchainData from './blockchain-data/index'; export { ImxApiClients } from './imx-api-clients'; export { MultiRollupApiClients } from './mr-api-clients'; export { - ImmutableAPIConfiguration, imxApiConfig, - multiRollupConfig, - MultiRollupAPIConfiguration, - createConfig, + multiRollupConfig, createConfig, } from './config'; +export type { ImmutableAPIConfiguration, MultiRollupAPIConfiguration } from './config'; diff --git a/packages/internal/generated-clients/tsconfig.json b/packages/internal/generated-clients/tsconfig.json index 56c27e347a..e43a0c438f 100644 --- a/packages/internal/generated-clients/tsconfig.json +++ b/packages/internal/generated-clients/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/checkout/sdk-sample-app/.eslintrc b/packages/internal/guardian/.eslintrc.cjs similarity index 55% rename from packages/checkout/sdk-sample-app/.eslintrc rename to packages/internal/guardian/.eslintrc.cjs index 664e0e3da5..cc10d70796 100644 --- a/packages/checkout/sdk-sample-app/.eslintrc +++ b/packages/internal/guardian/.eslintrc.cjs @@ -1,9 +1,8 @@ -{ +module.exports = { + "extends": ["../.eslintrc"], "parser": "@typescript-eslint/parser", - "ignorePatterns": ".", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": ".", - "sourceType": "module" + "tsconfigRootDir": __dirname } } diff --git a/packages/internal/guardian/tsconfig.json b/packages/internal/guardian/tsconfig.json index f587a4939e..05087f2b94 100644 --- a/packages/internal/guardian/tsconfig.json +++ b/packages/internal/guardian/tsconfig.json @@ -1,24 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", - "rootDirs": [ - "src" - ], - "target": "es2022", - "module": "es2022", - "moduleResolution": "node", - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "noFallthroughCasesInSwitch": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "declaration": true + "rootDirs": ["src"], }, "include": [ "src" diff --git a/packages/game-bridge/.eslintrc b/packages/internal/metrics/.eslintrc.cjs similarity index 55% rename from packages/game-bridge/.eslintrc rename to packages/internal/metrics/.eslintrc.cjs index f90c594b06..cc10d70796 100644 --- a/packages/game-bridge/.eslintrc +++ b/packages/internal/metrics/.eslintrc.cjs @@ -1,8 +1,8 @@ -{ - "extends": ["../../.eslintrc"], +module.exports = { + "extends": ["../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname } } diff --git a/packages/internal/metrics/src/index.ts b/packages/internal/metrics/src/index.ts index 323f48a335..e5ea7db07d 100644 --- a/packages/internal/metrics/src/index.ts +++ b/packages/internal/metrics/src/index.ts @@ -3,7 +3,8 @@ import * as localStorage from './utils/localStorage'; export { track } from './track'; export { trackDuration } from './performance'; -export { Flow, trackFlow } from './flow'; +export { trackFlow } from './flow'; +export type { Flow } from './flow'; export { trackError } from './error'; export { identify } from './identify'; export { diff --git a/packages/internal/metrics/tsconfig.json b/packages/internal/metrics/tsconfig.json index fc204f35c4..f09a2d6e5c 100644 --- a/packages/internal/metrics/tsconfig.json +++ b/packages/internal/metrics/tsconfig.json @@ -1,109 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "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": "es2022", /* 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": "esnext", /* Specify what module code is generated. */ - // "rootDir": "./src", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - "rootDirs": ["src"], /* 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": false, /* 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. */ - - /* Advanced */ - // "noEmit": true, - // "allowJs": false, - // "allowSyntheticDefaultImports": true, - // "resolveJsonModule": true, + "outDir": "./dist", + "rootDirs": ["src"], }, "include": ["src"], "exclude": ["dist", "jest.config.js", "node_modules"] diff --git a/packages/internal/toolkit/package.json b/packages/internal/toolkit/package.json index e015d69f35..760318f448 100644 --- a/packages/internal/toolkit/package.json +++ b/packages/internal/toolkit/package.json @@ -9,7 +9,7 @@ "@ethersproject/providers": "^5.7.2", "@ethersproject/wallet": "^5.7.0", "@imtbl/x-client": "0.0.0", - "@magic-ext/oidc": "4.2.0", + "@magic-ext/oidc": "4.3.1", "@metamask/detect-provider": "^2.0.0", "axios": "^1.6.5", "bn.js": "^5.2.1", diff --git a/packages/internal/toolkit/tsconfig.json b/packages/internal/toolkit/tsconfig.json index 7dbb9f1fb9..0813bd4336 100644 --- a/packages/internal/toolkit/tsconfig.json +++ b/packages/internal/toolkit/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist", "src/sample-app"] diff --git a/packages/minting-backend/sdk/.eslintrc b/packages/minting-backend/sdk/.eslintrc.cjs similarity index 79% rename from packages/minting-backend/sdk/.eslintrc rename to packages/minting-backend/sdk/.eslintrc.cjs index f77729693e..3193df85c8 100644 --- a/packages/minting-backend/sdk/.eslintrc +++ b/packages/minting-backend/sdk/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/comma-dangle": "off" diff --git a/packages/minting-backend/sdk/tsconfig.json b/packages/minting-backend/sdk/tsconfig.json index 56c27e347a..e43a0c438f 100644 --- a/packages/minting-backend/sdk/tsconfig.json +++ b/packages/minting-backend/sdk/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/orderbook/.eslintrc b/packages/orderbook/.eslintrc.cjs similarity index 92% rename from packages/orderbook/.eslintrc rename to packages/orderbook/.eslintrc.cjs index 38e5c14091..aaaaae145f 100644 --- a/packages/orderbook/.eslintrc +++ b/packages/orderbook/.eslintrc.cjs @@ -1,10 +1,10 @@ -{ - "extends": ["airbnb", "airbnb-typescript"], +module.exports = { + "extends": ["../../.eslintrc", "airbnb", "airbnb-typescript"], "ignorePatterns": ["jest.config.*"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/naming-convention": [ diff --git a/packages/orderbook/src/index.ts b/packages/orderbook/src/index.ts index 2d42a79ff8..e92417f45d 100644 --- a/packages/orderbook/src/index.ts +++ b/packages/orderbook/src/index.ts @@ -1,4 +1,4 @@ export { Orderbook } from './orderbook'; export { constants } from './constants'; -export { OrderbookModuleConfiguration, OrderbookOverrides } from './config'; +export type { OrderbookModuleConfiguration, OrderbookOverrides } from './config'; export * from './types'; diff --git a/packages/orderbook/tsconfig.json b/packages/orderbook/tsconfig.json index 56c27e347a..ee6d658245 100644 --- a/packages/orderbook/tsconfig.json +++ b/packages/orderbook/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/passport/sdk/.eslintrc b/packages/passport/sdk/.eslintrc.cjs similarity index 90% rename from packages/passport/sdk/.eslintrc rename to packages/passport/sdk/.eslintrc.cjs index 4fd603ea90..a617575b17 100644 --- a/packages/passport/sdk/.eslintrc +++ b/packages/passport/sdk/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/naming-convention": [ diff --git a/packages/passport/sdk/package.json b/packages/passport/sdk/package.json index 464636ec92..a64bae0ffe 100644 --- a/packages/passport/sdk/package.json +++ b/packages/passport/sdk/package.json @@ -15,7 +15,7 @@ "@imtbl/toolkit": "0.0.0", "@imtbl/x-client": "0.0.0", "@imtbl/x-provider": "0.0.0", - "@magic-ext/oidc": "4.2.0", + "@magic-ext/oidc": "4.3.1", "@metamask/detect-provider": "^2.0.0", "axios": "^1.6.5", "ethers": "^5.7.2", diff --git a/packages/passport/sdk/src/index.ts b/packages/passport/sdk/src/index.ts index 7a782c1ed8..f9411a0dc6 100644 --- a/packages/passport/sdk/src/index.ts +++ b/packages/passport/sdk/src/index.ts @@ -1,13 +1,14 @@ export { PassportError } from './errors/passportError'; export { Passport } from './Passport'; export { + ProviderEvent, +} from './zkEvm/types'; +export type { RequestArguments, JsonRpcRequestPayload, JsonRpcResponsePayload, JsonRpcRequestCallback, - Provider, - ProviderEvent, - AccountsChangedEvent, + Provider, AccountsChangedEvent, TypedDataPayload, } from './zkEvm/types'; export { @@ -15,7 +16,7 @@ export { ProviderErrorCode, RpcErrorCode, } from './zkEvm/JsonRpcError'; -export { +export type { LinkWalletParams, LinkedWallet, UserProfile, diff --git a/packages/passport/sdk/tsconfig.json b/packages/passport/sdk/tsconfig.json index 34907d4105..313a445552 100644 --- a/packages/passport/sdk/tsconfig.json +++ b/packages/passport/sdk/tsconfig.json @@ -1,26 +1,12 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src", "src/types.ts"], "exclude": [ "node_modules", "dist", - "src/modules/provider/sample-app", - "src/modules/checkout" ] } diff --git a/packages/webhook/sdk/.eslintrc b/packages/webhook/sdk/.eslintrc.cjs similarity index 79% rename from packages/webhook/sdk/.eslintrc rename to packages/webhook/sdk/.eslintrc.cjs index f77729693e..3193df85c8 100644 --- a/packages/webhook/sdk/.eslintrc +++ b/packages/webhook/sdk/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/comma-dangle": "off" diff --git a/packages/webhook/sdk/src/index.ts b/packages/webhook/sdk/src/index.ts index d1149bdc6b..7943f8d197 100644 --- a/packages/webhook/sdk/src/index.ts +++ b/packages/webhook/sdk/src/index.ts @@ -19,6 +19,6 @@ export type { } from './event-types'; export { - handle, - WebhookHandlers + handle }; +export type { WebhookHandlers }; diff --git a/packages/webhook/sdk/tsconfig.json b/packages/webhook/sdk/tsconfig.json index 56c27e347a..e43a0c438f 100644 --- a/packages/webhook/sdk/tsconfig.json +++ b/packages/webhook/sdk/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/checkout/.eslintrc b/packages/x-client/.eslintrc.cjs similarity index 72% rename from packages/checkout/.eslintrc rename to packages/x-client/.eslintrc.cjs index f90c594b06..8b8a821f7e 100644 --- a/packages/checkout/.eslintrc +++ b/packages/x-client/.eslintrc.cjs @@ -1,8 +1,8 @@ -{ +module.exports = { "extends": ["../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname } } diff --git a/packages/x-client/src/index.ts b/packages/x-client/src/index.ts index 54dffc49bd..f484a40791 100644 --- a/packages/x-client/src/index.ts +++ b/packages/x-client/src/index.ts @@ -6,9 +6,9 @@ export * from './types'; /** * aliased exports to maintain backwards compatibility */ -export { ImxModuleConfiguration as ImxClientModuleConfiguration } from './config'; +export type { ImxModuleConfiguration as ImxClientModuleConfiguration } from './config'; export { generateLegacyStarkPrivateKey as imxClientGenerateLegacyStarkPrivateKey, createStarkSigner as imxClientCreateStarkSigner, } from './exportUtils'; -export { WalletConnection as ImxClientWalletConnection } from './types'; +export type { WalletConnection as ImxClientWalletConnection } from './types'; diff --git a/packages/x-client/src/types/api.ts b/packages/x-client/src/types/api.ts index 9509146795..669119d3f5 100644 --- a/packages/x-client/src/types/api.ts +++ b/packages/x-client/src/types/api.ts @@ -2,7 +2,7 @@ /* eslint-disable max-len */ import { imx } from '@imtbl/generated-clients'; -export { TransactionResponse } from '@ethersproject/providers'; +export type { TransactionResponse } from '@ethersproject/providers'; /** * Need to specifically export the classes and interfaces from the generated @@ -99,4 +99,11 @@ export interface UpdateCollectionRequest extends imx.UpdateCollectionRequest {} export interface WithdrawalsApiGetWithdrawalRequest extends imx.WithdrawalsApiGetWithdrawalRequest {} export interface WithdrawalsApiListWithdrawalsRequest extends imx.WithdrawalsApiListWithdrawalsRequest {} -export const { MetadataSchemaRequestTypeEnum } = imx; +// eslint-disable-next-line prefer-destructuring +export const MetadataSchemaRequestTypeEnum: { + readonly Enum: 'enum'; + readonly Text: 'text'; + readonly Boolean: 'boolean'; + readonly Continuous: 'continuous'; + readonly Discrete: 'discrete'; +} = imx.MetadataSchemaRequestTypeEnum; diff --git a/packages/x-client/tsconfig.json b/packages/x-client/tsconfig.json index 6a6643584c..f42e62aedc 100644 --- a/packages/x-client/tsconfig.json +++ b/packages/x-client/tsconfig.json @@ -1,19 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, "skipLibCheck": true }, "include": ["src"], diff --git a/packages/x-provider/.eslintrc b/packages/x-provider/.eslintrc.cjs similarity index 86% rename from packages/x-provider/.eslintrc rename to packages/x-provider/.eslintrc.cjs index 214bef5de8..a43b4737b9 100644 --- a/packages/x-provider/.eslintrc +++ b/packages/x-provider/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "@typescript-eslint/naming-convention": [ diff --git a/packages/x-provider/package.json b/packages/x-provider/package.json index cbd9c2ed38..39760dc8e7 100644 --- a/packages/x-provider/package.json +++ b/packages/x-provider/package.json @@ -9,7 +9,7 @@ "@imtbl/generated-clients": "0.0.0", "@imtbl/toolkit": "0.0.0", "@imtbl/x-client": "0.0.0", - "@magic-ext/oidc": "4.2.0", + "@magic-ext/oidc": "4.3.1", "@metamask/detect-provider": "^2.0.0", "axios": "^1.6.5", "ethers": "^5.7.2", diff --git a/packages/x-provider/src/index.ts b/packages/x-provider/src/index.ts index de85e1a08b..99bc94293d 100644 --- a/packages/x-provider/src/index.ts +++ b/packages/x-provider/src/index.ts @@ -1,4 +1,4 @@ -export { IMXProvider } from './imxProvider'; +export type { IMXProvider } from './imxProvider'; export { GenericIMXProvider } from './genericImxProvider'; export { MetaMaskIMXProvider } from './l1-providers/metaMaskWrapper'; export { ProviderConfiguration } from './config'; diff --git a/packages/x-provider/src/sample-app/.env b/packages/x-provider/src/sample-app/.env new file mode 100644 index 0000000000..02269f00d9 --- /dev/null +++ b/packages/x-provider/src/sample-app/.env @@ -0,0 +1 @@ +DISABLE_ESLINT_PLUGIN=true diff --git a/packages/x-provider/src/sample-app/.gitignore b/packages/x-provider/src/sample-app/.gitignore index 0d956b3213..d170858507 100644 --- a/packages/x-provider/src/sample-app/.gitignore +++ b/packages/x-provider/src/sample-app/.gitignore @@ -17,6 +17,7 @@ node_modules .env.development.local .env.test.local .env.production.local +!.env npm-debug.log* yarn-debug.log* diff --git a/packages/x-provider/tsconfig.json b/packages/x-provider/tsconfig.json index 7dbb9f1fb9..6d8bc46f04 100644 --- a/packages/x-provider/tsconfig.json +++ b/packages/x-provider/tsconfig.json @@ -1,20 +1,8 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": true, - "resolveJsonModule": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist", "src/sample-app"] diff --git a/sdk/.eslintrc b/sdk/.eslintrc.cjs similarity index 75% rename from sdk/.eslintrc rename to sdk/.eslintrc.cjs index 9cf76ec00c..515261c86d 100644 --- a/sdk/.eslintrc +++ b/sdk/.eslintrc.cjs @@ -1,9 +1,10 @@ -{ +module.exports = { "ignorePatterns": ["jest.config.*"], + "extends": ["../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": ".", + "tsconfigRootDir": __dirname, "sourceType": "module" }, "rules": { diff --git a/sdk/package.json b/sdk/package.json index ae744e072b..b6ff70fb86 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -18,7 +18,7 @@ "@ethersproject/wallet": "^5.7.0", "@imtbl/react-analytics": "0.2.1-alpha", "@jest/globals": "^29.5.0", - "@magic-ext/oidc": "4.2.0", + "@magic-ext/oidc": "4.3.1", "@metamask/detect-provider": "^2.0.0", "@opensea/seaport-js": "4.0.3", "@rive-app/react-canvas-lite": "^4.9.0", diff --git a/sdk/tsconfig.json b/sdk/tsconfig.json index 2057e61172..30f13daf53 100644 --- a/sdk/tsconfig.json +++ b/sdk/tsconfig.json @@ -1,26 +1,12 @@ { + "extends": "../tsconfig.base.json", "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "target": "es2022", - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "allowJs": false, - "removeComments": false, - "strict": true, - "forceConsistentCasingInFileNames": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "declaration": false, - "resolveJsonModule": true, - "skipLibCheck": false }, "include": ["src"], "exclude": [ "node_modules", - "dist", - "src/modules/provider/sample-app", - "src/modules/checkout" + "dist" ] } diff --git a/tests/func-tests/zkevm/tsconfig.json b/tests/func-tests/zkevm/tsconfig.json new file mode 100644 index 0000000000..e05ca5f05c --- /dev/null +++ b/tests/func-tests/zkevm/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDirs": ["src"], + }, + "include": ["src"], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/tsconfig.json b/tsconfig.base.json similarity index 80% rename from tsconfig.json rename to tsconfig.base.json index 333e556c0f..f6bd61966a 100644 --- a/tsconfig.json +++ b/tsconfig.base.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "jsx": "react", "target": "es2022", "module": "esnext", "moduleResolution": "node", @@ -11,9 +10,11 @@ "forceConsistentCasingInFileNames": false, "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "declaration": false, + "declaration": true, "resolveJsonModule": true, - "skipLibCheck": true + "skipLibCheck": false, + "isolatedModules": true, + "incremental": true }, "ts-node": { "compilerOptions": { diff --git a/yarn.lock b/yarn.lock index dad3d6bc7e..1cb4b81ffc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4381,6 +4381,7 @@ __metadata: local-cypress: ^1.2.6 os-browserify: ^0.3.0 pako: ^2.1.0 + pino-pretty: ^11.2.2 react-app-rewired: ^2.2.1 react-i18next: ^13.5.0 react-scripts: 5.0.1 @@ -4685,7 +4686,7 @@ __metadata: "@imtbl/toolkit": 0.0.0 "@imtbl/x-client": 0.0.0 "@imtbl/x-provider": 0.0.0 - "@magic-ext/oidc": 4.2.0 + "@magic-ext/oidc": 4.3.1 "@metamask/detect-provider": ^2.0.0 "@rollup/plugin-typescript": ^11.1.6 "@swc/core": ^1.3.36 @@ -4761,7 +4762,7 @@ __metadata: "@imtbl/x-client": 0.0.0 "@imtbl/x-provider": 0.0.0 "@jest/globals": ^29.5.0 - "@magic-ext/oidc": 4.2.0 + "@magic-ext/oidc": 4.3.1 "@metamask/detect-provider": ^2.0.0 "@opensea/seaport-js": 4.0.3 "@rive-app/react-canvas-lite": ^4.9.0 @@ -4901,7 +4902,7 @@ __metadata: "@ethersproject/providers": ^5.7.2 "@ethersproject/wallet": ^5.7.0 "@imtbl/x-client": 0.0.0 - "@magic-ext/oidc": 4.2.0 + "@magic-ext/oidc": 4.3.1 "@metamask/detect-provider": ^2.0.0 "@rollup/plugin-typescript": ^11.1.6 "@swc/core": ^1.3.36 @@ -4990,7 +4991,7 @@ __metadata: "@imtbl/generated-clients": 0.0.0 "@imtbl/toolkit": 0.0.0 "@imtbl/x-client": 0.0.0 - "@magic-ext/oidc": 4.2.0 + "@magic-ext/oidc": 4.3.1 "@metamask/detect-provider": ^2.0.0 "@rollup/plugin-typescript": ^11.1.6 "@swc/core": ^1.3.36 @@ -6231,6 +6232,13 @@ __metadata: languageName: node linkType: hard +"@magic-ext/oidc@npm:4.3.1": + version: 4.3.1 + resolution: "@magic-ext/oidc@npm:4.3.1" + checksum: 1eb1e2869b4acdb035b6e17244c835cd9a1c6d464ef666c827007e431da65c6fc7cd3e8c657b690f74ac01e4659336687aa336df57a315d5f34832721390b002 + languageName: node + linkType: hard + "@magic-sdk/commons@npm:^17.2.0": version: 17.2.0 resolution: "@magic-sdk/commons@npm:17.2.0" @@ -21705,7 +21713,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8": +"eslint@npm:^8, eslint@npm:^8.40.0": version: 8.57.0 resolution: "eslint@npm:8.57.0" dependencies: @@ -21753,7 +21761,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.3.0, eslint@npm:^8.40.0": +"eslint@npm:^8.3.0": version: 8.45.0 resolution: "eslint@npm:8.45.0" dependencies: From 50b953c68ae66507ff4ee1380620a87f877fba29 Mon Sep 17 00:00:00 2001 From: Nik <2661899+CodeSchwert@users.noreply.github.com> Date: Thu, 8 Aug 2024 18:40:14 +1200 Subject: [PATCH 02/29] fix: x client missing response types (#2083) --- .husky/pre-commit | 3 + packages/x-client/src/IMXClient.ts | 171 ++++++++++++------ packages/x-client/src/types/api.ts | 45 ++++- .../x-client/src/workflows/primarySales.ts | 6 +- packages/x-client/src/workflows/workflows.ts | 6 + 5 files changed, 171 insertions(+), 60 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 5a182ef106..5571608bdd 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,7 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" +# prevent heap limit allocation errors +export NODE_OPTIONS="--max-old-space-size=4096" + yarn lint-staged diff --git a/packages/x-client/src/IMXClient.ts b/packages/x-client/src/IMXClient.ts index 85971ccd09..cdef8f66f3 100644 --- a/packages/x-client/src/IMXClient.ts +++ b/packages/x-client/src/IMXClient.ts @@ -4,65 +4,108 @@ import { ImxModuleConfiguration, } from './config'; import { formatError } from './utils/formatError'; -import { +import type { AddMetadataSchemaToCollectionRequest, + Asset, AssetsApi, AssetsApiGetAssetRequest, AssetsApiListAssetsRequest, + Balance, BalancesApi, BalancesApiGetBalanceRequest, BalancesApiListBalancesRequest, + Collection, + CollectionFilter, CollectionsApi, CollectionsApiGetCollectionRequest, CollectionsApiListCollectionFiltersRequest, CollectionsApiListCollectionsRequest, CreateCollectionRequest, CreateMetadataRefreshRequest, + CreateMetadataRefreshResponse, + CreateTransferResponseV1, + CurrencyWithLimits, + Deposit, DepositsApi, DepositsApiGetDepositRequest, DepositsApiListDepositsRequest, EncodingApi, EthSigner, + Exchange, + ExchangeCreateExchangeAndURLResponse, ExchangesApi, ExchangesApiCreateExchangeRequest, ExchangesApiGetExchangeRequest, ExchangesApiGetExchangesRequest, - MintsApi, - MintsApiGetMintRequest, - MintsApiListMintsRequest, + GetMetadataRefreshErrorsResponse, + GetMetadataRefreshes, + GetMetadataRefreshResponse, + GetTransactionsResponse, + GetUsersApiResponse, + ListAssetsResponse, + ListBalancesResponse, + ListCollectionsResponse, + ListDepositsResponse, + ListMintsResponse, + ListOrdersResponseV3, + ListTokensResponse, + ListTradesResponse, + ListTransfersResponse, + ListWithdrawalsResponse, MetadataApi, MetadataApiGetMetadataSchemaRequest, MetadataRefreshesApi, + MetadataSchemaProperty, MetadataSchemaRequest, + Mint, + MintsApi, + MintsApiGetMintRequest, + MintsApiListMintsRequest, + MintTokensResponse, NftCheckoutPrimaryApi, NftCheckoutPrimaryApiCreateNftPrimaryRequest, NftCheckoutPrimaryApiGetCurrenciesNFTCheckoutPrimaryRequest, NftCheckoutPrimaryApiGetNftPrimaryTransactionRequest, NftCheckoutPrimaryApiGetNftPrimaryTransactionsRequest, + NftprimarytransactionCreateResponse, + NftprimarytransactionGetResponse, + NftprimarytransactionListTransactionsResponse, OrdersApi, OrdersApiGetOrderV3Request, OrdersApiListOrdersV3Request, + OrderV3, PrimarySalesApi, PrimarySalesApiSignableCreatePrimarySaleRequest, + Project, ProjectsApi, + SuccessResponse, + TokenDetails, TokensApi, TokensApiGetTokenRequest, TokensApiListTokensRequest, + Trade, TradesApi, TradesApiGetTradeV3Request, TradesApiListTradesV3Request, + Transfer, TransfersApi, TransfersApiGetTransferRequest, TransfersApiListTransfersRequest, - UpdateCollectionRequest, - UnsignedMintRequest, - WalletConnection, UnsignedExchangeTransferRequest, + UnsignedMintRequest, + UpdateCollectionRequest, UsersApi, + WalletConnection, + Withdrawal, WithdrawalsApi, WithdrawalsApiGetWithdrawalRequest, WithdrawalsApiListWithdrawalsRequest, } from './types'; +import type { + AcceptPrimarySaleResponse, + CreatePrimarySaleResponse, + RejectPrimarySaleResponse, +} from './workflows'; import { Workflows } from './workflows'; export class IMXClient { @@ -147,7 +190,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Deposit * @throws {@link IMXError} */ - public getDeposit(request: DepositsApiGetDepositRequest) { + public getDeposit(request: DepositsApiGetDepositRequest): Promise { return this.depositsApi .getDeposit(request) .then((res) => res.data) @@ -162,7 +205,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Deposits * @throws {@link IMXError} */ - public listDeposits(request?: DepositsApiListDepositsRequest) { + public listDeposits(request?: DepositsApiListDepositsRequest): Promise { return this.depositsApi .listDeposits(request) .then((res) => res.data) @@ -177,7 +220,7 @@ export class IMXClient { * @returns a promise that resolves with the requested User * @throws {@link IMXError} */ - public getUser(ethAddress: string) { + public getUser(ethAddress: string): Promise { return this.usersApi .getUsers({ user: ethAddress }) .then((res) => res.data) @@ -192,7 +235,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Asset * @throws {@link IMXError} */ - public getAsset(request: AssetsApiGetAssetRequest) { + public getAsset(request: AssetsApiGetAssetRequest): Promise { return this.assetApi .getAsset(request) .then((res) => res.data) @@ -207,7 +250,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Assets * @throws {@link IMXError} */ - public listAssets(request?: AssetsApiListAssetsRequest) { + public listAssets(request?: AssetsApiListAssetsRequest): Promise { return this.assetApi .listAssets(request) .then((res) => res.data) @@ -226,7 +269,7 @@ export class IMXClient { public createCollection( ethSigner: EthSigner, request: CreateCollectionRequest, - ) { + ): Promise { return this.workflows .createCollection(ethSigner, request) .then((res) => res.data) @@ -241,7 +284,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Collection * @throws {@link IMXError} */ - public getCollection(request: CollectionsApiGetCollectionRequest) { + public getCollection(request: CollectionsApiGetCollectionRequest): Promise { return this.collectionApi .getCollection(request) .then((res) => res.data) @@ -258,7 +301,7 @@ export class IMXClient { */ public listCollectionFilters( request: CollectionsApiListCollectionFiltersRequest, - ) { + ): Promise { return this.collectionApi .listCollectionFilters(request) .then((res) => res.data) @@ -273,7 +316,9 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Collections * @throws {@link IMXError} */ - public listCollections(request?: CollectionsApiListCollectionsRequest) { + public listCollections( + request?: CollectionsApiListCollectionsRequest, + ): Promise { return this.collectionApi .listCollections(request) .then((res) => res.data) @@ -294,7 +339,7 @@ export class IMXClient { ethSigner: EthSigner, collectionAddress: string, request: UpdateCollectionRequest, - ) { + ): Promise { return this.workflows .updateCollection(ethSigner, collectionAddress, request) .then((res) => res.data) @@ -315,7 +360,7 @@ export class IMXClient { ethSigner: EthSigner, collectionAddress: string, request: AddMetadataSchemaToCollectionRequest, - ) { + ): Promise { return this.workflows .addMetadataSchemaToCollection(ethSigner, collectionAddress, request) .then((res) => res.data) @@ -330,7 +375,9 @@ export class IMXClient { * @returns a promise that resolves with the requested Metadata schema * @throws {@link IMXError} */ - public getMetadataSchema(request: MetadataApiGetMetadataSchemaRequest) { + public getMetadataSchema( + request: MetadataApiGetMetadataSchemaRequest, + ): Promise { return this.metadataApi .getMetadataSchema(request) .then((res) => res.data) @@ -345,7 +392,7 @@ export class IMXClient { * @param collectionAddress - the Collection contract address * @param name - the Metadata schema name * @param request - the request object containing the parameters to be provided in the API request - * @returns a promise that resolves with the SuccessResponse if successful + * @returns a promise that resolves with the {@link SuccessResponse} * @throws {@link IMXError} */ public updateMetadataSchemaByName( @@ -353,7 +400,7 @@ export class IMXClient { collectionAddress: string, name: string, request: MetadataSchemaRequest, - ) { + ): Promise { return this.workflows .updateMetadataSchemaByName(ethSigner, collectionAddress, name, request) .then((res) => res.data) @@ -376,7 +423,7 @@ export class IMXClient { collectionAddress?: string, pageSize?: number, cursor?: string, - ) { + ): Promise { return this.workflows .listMetadataRefreshes(ethSigner, collectionAddress, pageSize, cursor) .then((res) => res.data) @@ -399,7 +446,7 @@ export class IMXClient { refreshId: string, pageSize?: number, cursor?: string, - ) { + ): Promise { return this.workflows .getMetadataRefreshErrors(ethSigner, refreshId, pageSize, cursor) .then((res) => res.data) @@ -415,7 +462,10 @@ export class IMXClient { * @returns a promise that resolves with the requested metadata refresh results * @throws {@link IMXError} */ - public getMetadataRefreshResults(ethSigner: EthSigner, refreshId: string) { + public getMetadataRefreshResults( + ethSigner: EthSigner, + refreshId: string, + ): Promise { return this.workflows .getMetadataRefreshResults(ethSigner, refreshId) .then((res) => res.data) @@ -434,7 +484,7 @@ export class IMXClient { public createMetadataRefresh( ethSigner: EthSigner, request: CreateMetadataRefreshRequest, - ) { + ): Promise { return this.workflows .createMetadataRefresh(ethSigner, request) .then((res) => res.data) @@ -450,7 +500,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Project * @throws {@link IMXError} */ - public async getProject(ethSigner: EthSigner, id: string) { + public async getProject(ethSigner: EthSigner, id: string): Promise { return this.workflows .getProject(ethSigner, id) .then((res) => res.data) @@ -465,7 +515,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Balance * @throws {@link IMXError} */ - public getBalance(request: BalancesApiGetBalanceRequest) { + public getBalance(request: BalancesApiGetBalanceRequest): Promise { return this.balanceApi .getBalance(request) .then((res) => res.data) @@ -480,7 +530,9 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Balances * @throws {@link IMXError} */ - public listBalances(request: BalancesApiListBalancesRequest) { + public listBalances( + request: BalancesApiListBalancesRequest, + ): Promise { return this.balanceApi .listBalances(request) .then((res) => res.data) @@ -495,7 +547,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Mint * @throws {@link IMXError} */ - public getMint(request: MintsApiGetMintRequest) { + public getMint(request: MintsApiGetMintRequest): Promise { return this.mintsApi .getMint(request) .then((res) => res.data) @@ -510,7 +562,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Mints * @throws {@link IMXError} */ - public listMints(request?: MintsApiListMintsRequest) { + public listMints(request?: MintsApiListMintsRequest): Promise { return this.mintsApi .listMints(request) .then((res) => res.data) @@ -526,7 +578,10 @@ export class IMXClient { * @returns a promise that resolves with the minted tokens * @throws {@link IMXError} */ - public mint(ethSigner: EthSigner, request: UnsignedMintRequest) { + public mint( + ethSigner: EthSigner, + request: UnsignedMintRequest, + ): Promise { return this.workflows.mint(ethSigner, request); } @@ -536,7 +591,9 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Withdrawals * @throws {@link IMXError} */ - public listWithdrawals(request?: WithdrawalsApiListWithdrawalsRequest) { + public listWithdrawals( + request?: WithdrawalsApiListWithdrawalsRequest, + ): Promise { return this.withdrawalsApi .listWithdrawals(request) .then((res) => res.data) @@ -551,7 +608,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Withdrawal * @throws {@link IMXError} */ - public getWithdrawal(request: WithdrawalsApiGetWithdrawalRequest) { + public getWithdrawal(request: WithdrawalsApiGetWithdrawalRequest): Promise { return this.withdrawalsApi .getWithdrawal(request) .then((res) => res.data) @@ -566,7 +623,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Order * @throws {@link IMXError} */ - public getOrder(request: OrdersApiGetOrderV3Request) { + public getOrder(request: OrdersApiGetOrderV3Request): Promise { return this.ordersApi .getOrderV3(request) .then((res) => res.data) @@ -581,7 +638,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Orders * @throws {@link IMXError} */ - public listOrders(request?: OrdersApiListOrdersV3Request) { + public listOrders(request?: OrdersApiListOrdersV3Request): Promise { return this.ordersApi .listOrdersV3(request) .then((res) => res.data) @@ -596,7 +653,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Trade * @throws {@link IMXError} */ - public getTrade(request: TradesApiGetTradeV3Request) { + public getTrade(request: TradesApiGetTradeV3Request): Promise { return this.tradesApi .getTradeV3(request) .then((res) => res.data) @@ -611,7 +668,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Trades * @throws {@link IMXError} */ - public listTrades(request?: TradesApiListTradesV3Request) { + public listTrades(request?: TradesApiListTradesV3Request): Promise { return this.tradesApi .listTradesV3(request) .then((res) => res.data) @@ -626,7 +683,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Token * @throws {@link IMXError} */ - public getToken(request: TokensApiGetTokenRequest) { + public getToken(request: TokensApiGetTokenRequest): Promise { return this.tokensApi .getToken(request) .then((res) => res.data) @@ -641,7 +698,7 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Tokens * @throws {@link IMXError} */ - public listTokens(request?: TokensApiListTokensRequest) { + public listTokens(request?: TokensApiListTokensRequest): Promise { return this.tokensApi .listTokens(request) .then((res) => res.data) @@ -656,7 +713,7 @@ export class IMXClient { * @returns a promise that resolves with the requested Transfer * @throws {@link IMXError} */ - public getTransfer(request: TransfersApiGetTransferRequest) { + public getTransfer(request: TransfersApiGetTransferRequest): Promise { return this.transfersApi .getTransfer(request) .then((res) => res.data) @@ -671,7 +728,9 @@ export class IMXClient { * @returns a promise that resolves with the requested list of Transfers * @throws {@link IMXError} */ - public listTransfers(request?: TransfersApiListTransfersRequest) { + public listTransfers( + request?: TransfersApiListTransfersRequest, + ): Promise { return this.transfersApi .listTransfers(request) .then((res) => res.data) @@ -686,7 +745,9 @@ export class IMXClient { * @returns a promise that resolves with the created Exchange Transaction * @throws {@link IMXError} */ - public createExchange(request: ExchangesApiCreateExchangeRequest) { + public createExchange( + request: ExchangesApiCreateExchangeRequest, + ): Promise { return this.exchangeApi.createExchange(request) .then((res) => res.data) .catch((err) => { @@ -700,7 +761,7 @@ export class IMXClient { * @returns a promise that resolves with the Exchange Transaction * @throws {@link IMXError} */ - public getExchange(request: ExchangesApiGetExchangeRequest) { + public getExchange(request: ExchangesApiGetExchangeRequest): Promise { return this.exchangeApi.getExchange(request) .then((res) => res.data) .catch((err) => { @@ -714,7 +775,7 @@ export class IMXClient { * @returns a promise that resolves with Exchange Transactions * @throws {@link IMXError} */ - public getExchanges(request: ExchangesApiGetExchangesRequest) { + public getExchanges(request: ExchangesApiGetExchangesRequest): Promise { return this.exchangeApi.getExchanges(request) .then((res) => res.data) .catch((err) => { @@ -732,7 +793,7 @@ export class IMXClient { public exchangeTransfer( walletConnection: WalletConnection, request: UnsignedExchangeTransferRequest, - ) { + ): Promise { return this.workflows.exchangeTransfer(walletConnection, request); } @@ -744,7 +805,7 @@ export class IMXClient { */ public createNftPrimary( request: NftCheckoutPrimaryApiCreateNftPrimaryRequest, - ) { + ): Promise { return this.nftCheckoutPrimaryApi.createNftPrimary(request) .then((res) => res.data) .catch((err) => { @@ -760,7 +821,7 @@ export class IMXClient { */ public getCurrenciesNFTCheckoutPrimary( request: NftCheckoutPrimaryApiGetCurrenciesNFTCheckoutPrimaryRequest, - ) { + ): Promise { return this.nftCheckoutPrimaryApi .getCurrenciesNFTCheckoutPrimary(request) .then((res) => res.data) @@ -777,7 +838,7 @@ export class IMXClient { */ public getNftPrimaryTransaction( request: NftCheckoutPrimaryApiGetNftPrimaryTransactionRequest, - ) { + ): Promise { return this.nftCheckoutPrimaryApi .getNftPrimaryTransaction(request) .then((res) => res.data) @@ -794,7 +855,7 @@ export class IMXClient { */ public getNftPrimaryTransactions( request: NftCheckoutPrimaryApiGetNftPrimaryTransactionsRequest, - ) { + ): Promise { return this.nftCheckoutPrimaryApi .getNftPrimaryTransactions(request) .then((res) => res.data) @@ -813,7 +874,7 @@ export class IMXClient { public createPrimarySale( walletConnection: WalletConnection, request: PrimarySalesApiSignableCreatePrimarySaleRequest, - ) { + ): Promise { return this.workflows .createPrimarySale(walletConnection, request) .catch((err) => { @@ -828,7 +889,10 @@ export class IMXClient { * @returns a promise that resolves with the created Trade * @throws {@link IMXError} */ - public acceptPrimarySale(ethSigner: EthSigner, primarySaleId: number) { + public acceptPrimarySale( + ethSigner: EthSigner, + primarySaleId: number, + ): Promise { return this.workflows .acceptPrimarySale(ethSigner, primarySaleId) .catch((err) => { @@ -843,7 +907,10 @@ export class IMXClient { * @returns a promise that resolves with the rejected PrimarySale * @throws {@link IMXError} */ - public rejectPrimarySale(ethSigner: EthSigner, primarySaleId: number) { + public rejectPrimarySale( + ethSigner: EthSigner, + primarySaleId: number, + ): Promise { return this.workflows .rejectPrimarySale(ethSigner, primarySaleId) .catch((err) => { diff --git a/packages/x-client/src/types/api.ts b/packages/x-client/src/types/api.ts index 669119d3f5..2c7a7eecad 100644 --- a/packages/x-client/src/types/api.ts +++ b/packages/x-client/src/types/api.ts @@ -28,24 +28,28 @@ export class TransfersApi extends imx.TransfersApi {} export class UsersApi extends imx.UsersApi {} export class WithdrawalsApi extends imx.WithdrawalsApi {} -export interface APIError extends imx.APIError {} export interface AcceptPrimarySaleBadRequestBody extends imx.AcceptPrimarySaleBadRequestBody {} export interface AcceptPrimarySaleForbiddenBody extends imx.AcceptPrimarySaleForbiddenBody {} export interface AcceptPrimarySaleNotFoundBody extends imx.AcceptPrimarySaleNotFoundBody {} export interface AcceptPrimarySaleOKBody extends imx.AcceptPrimarySaleOKBody {} export interface AcceptPrimarySaleUnauthorizedBody extends imx.AcceptPrimarySaleUnauthorizedBody {} export interface AddMetadataSchemaToCollectionRequest extends imx.AddMetadataSchemaToCollectionRequest {} +export interface APIError extends imx.APIError {} +export interface Asset extends imx.Asset {} export interface AssetsApiGetAssetRequest extends imx.AssetsApiGetAssetRequest {} export interface AssetsApiListAssetsRequest extends imx.AssetsApiListAssetsRequest {} export interface Balance extends imx.Balance {} export interface BalancesApiGetBalanceRequest extends imx.BalancesApiGetBalanceRequest {} export interface BalancesApiListBalancesRequest extends imx.BalancesApiListBalancesRequest {} export interface CancelOrderResponse extends imx.CancelOrderResponse {} +export interface Collection extends imx.Collection {} +export interface CollectionFilter extends imx.CollectionFilter {} export interface CollectionsApiGetCollectionRequest extends imx.CollectionsApiGetCollectionRequest {} export interface CollectionsApiListCollectionFiltersRequest extends imx.CollectionsApiListCollectionFiltersRequest {} export interface CollectionsApiListCollectionsRequest extends imx.CollectionsApiListCollectionsRequest {} export interface CreateCollectionRequest extends imx.CreateCollectionRequest {} export interface CreateMetadataRefreshRequest extends imx.CreateMetadataRefreshRequest {} +export interface CreateMetadataRefreshResponse extends imx.CreateMetadataRefreshResponse {} export interface CreateOrderResponse extends imx.CreateOrderResponse {} export interface CreatePrimarySaleBadRequestBody extends imx.CreatePrimarySaleBadRequestBody {} export interface CreatePrimarySaleCreatedBody extends imx.CreatePrimarySaleCreatedBody {} @@ -55,47 +59,78 @@ export interface CreatePrimarySaleUnauthorizedBody extends imx.CreatePrimarySale export interface CreateTradeResponse extends imx.CreateTradeResponse {} export interface CreateTransferResponseV1 extends imx.CreateTransferResponseV1 {} export interface CreateWithdrawalResponse extends imx.CreateWithdrawalResponse {} +export interface CurrencyWithLimits extends imx.CurrencyWithLimits {} +export interface Deposit extends imx.Deposit {} export interface DepositsApiGetDepositRequest extends imx.DepositsApiGetDepositRequest {} export interface DepositsApiListDepositsRequest extends imx.DepositsApiListDepositsRequest {} +export interface Exchange extends imx.Exchange {} +export interface ExchangeCreateExchangeAndURLResponse extends imx.ExchangeCreateExchangeAndURLResponse {} export interface ExchangesApiCreateExchangeRequest extends imx.ExchangesApiCreateExchangeRequest {} export interface ExchangesApiGetExchangeRequest extends imx.ExchangesApiGetExchangeRequest {} export interface ExchangesApiGetExchangesRequest extends imx.ExchangesApiGetExchangesRequest {} +export interface GetMetadataRefreshes extends imx.GetMetadataRefreshes {} +export interface GetMetadataRefreshErrorsResponse extends imx.GetMetadataRefreshErrorsResponse {} +export interface GetMetadataRefreshResponse extends imx.GetMetadataRefreshResponse {} export interface GetSignableCancelOrderRequest extends imx.GetSignableCancelOrderRequest {} export interface GetSignableOrderRequest extends imx.GetSignableOrderRequest {} export interface GetSignableTradeRequest extends imx.GetSignableTradeRequest {} +export interface GetTransactionsResponse extends imx.GetTransactionsResponse {} +export interface GetUsersApiResponse extends imx.GetUsersApiResponse {} +export interface ListAssetsResponse extends imx.ListAssetsResponse {} +export interface ListBalancesResponse extends imx.ListBalancesResponse {} +export interface ListCollectionsResponse extends imx.ListCollectionsResponse {} +export interface ListDepositsResponse extends imx.ListDepositsResponse {} +export interface ListMintsResponse extends imx.ListMintsResponse {} +export interface ListOrdersResponseV3 extends imx.ListOrdersResponseV3 {} +export interface ListTokensResponse extends imx.ListTokensResponse {} +export interface ListTradesResponse extends imx.ListTradesResponse {} +export interface ListTransfersResponse extends imx.ListTransfersResponse {} +export interface ListWithdrawalsResponse extends imx.ListWithdrawalsResponse {} export interface MetadataApiGetMetadataSchemaRequest extends imx.MetadataApiGetMetadataSchemaRequest {} +export interface MetadataSchemaProperty extends imx.MetadataSchemaProperty {} export interface MetadataSchemaRequest extends imx.MetadataSchemaRequest {} +export interface Mint extends imx.Mint {} export interface MintFee extends imx.MintFee {} -export interface MintResultDetails extends imx.MintResultDetails {} export interface MintRequest extends imx.MintRequest {} -export interface MintTokenDataV2 extends imx.MintTokenDataV2 {} -export interface MintTokensResponse extends imx.MintTokensResponse {} -export interface MintUser extends imx.MintUser {} +export interface MintResultDetails extends imx.MintResultDetails {} export interface MintsApiGetMintRequest extends imx.MintsApiGetMintRequest {} export interface MintsApiListMintsRequest extends imx.MintsApiListMintsRequest {} export interface MintsApiMintTokensRequest extends imx.MintsApiMintTokensRequest {} +export interface MintTokenDataV2 extends imx.MintTokenDataV2 {} +export interface MintTokensResponse extends imx.MintTokensResponse {} +export interface MintUser extends imx.MintUser {} export interface NftCheckoutPrimaryApiCreateNftPrimaryRequest extends imx.NftCheckoutPrimaryApiCreateNftPrimaryRequest {} export interface NftCheckoutPrimaryApiGetCurrenciesNFTCheckoutPrimaryRequest extends imx.NftCheckoutPrimaryApiGetCurrenciesNFTCheckoutPrimaryRequest {} export interface NftCheckoutPrimaryApiGetNftPrimaryTransactionRequest extends imx.NftCheckoutPrimaryApiGetNftPrimaryTransactionRequest {} export interface NftCheckoutPrimaryApiGetNftPrimaryTransactionsRequest extends imx.NftCheckoutPrimaryApiGetNftPrimaryTransactionsRequest {} +export interface NftprimarytransactionCreateResponse extends imx.NftprimarytransactionCreateResponse {} +export interface NftprimarytransactionGetResponse extends imx.NftprimarytransactionGetResponse {} +export interface NftprimarytransactionListTransactionsResponse extends imx.NftprimarytransactionListTransactionsResponse {} export interface OrdersApiCreateOrderV3Request extends imx.OrdersApiCreateOrderV3Request {} export interface OrdersApiGetOrderV3Request extends imx.OrdersApiGetOrderV3Request {} export interface OrdersApiListOrdersV3Request extends imx.OrdersApiListOrdersV3Request {} +export interface OrderV3 extends imx.OrderV3 {} export interface PrimarySalesApiCreatePrimarySaleRequest extends imx.PrimarySalesApiCreatePrimarySaleRequest {} export interface PrimarySalesApiSignableCreatePrimarySaleRequest extends imx.PrimarySalesApiSignableCreatePrimarySaleRequest {} +export interface Project extends imx.Project {} export interface RejectPrimarySaleBadRequestBody extends imx.RejectPrimarySaleBadRequestBody {} export interface RejectPrimarySaleForbiddenBody extends imx.RejectPrimarySaleForbiddenBody {} export interface RejectPrimarySaleNotFoundBody extends imx.RejectPrimarySaleNotFoundBody {} export interface RejectPrimarySaleOKBody extends imx.RejectPrimarySaleOKBody {} export interface RejectPrimarySaleUnauthorizedBody extends imx.RejectPrimarySaleUnauthorizedBody {} export interface SignableToken extends imx.SignableToken {} +export interface SuccessResponse extends imx.SuccessResponse {} +export interface TokenDetails extends imx.TokenDetails {} export interface TokensApiGetTokenRequest extends imx.TokensApiGetTokenRequest {} export interface TokensApiListTokensRequest extends imx.TokensApiListTokensRequest {} +export interface Trade extends imx.Trade {} export interface TradesApiGetTradeV3Request extends imx.TradesApiGetTradeV3Request {} export interface TradesApiListTradesV3Request extends imx.TradesApiListTradesV3Request {} +export interface Transfer extends imx.Transfer {} export interface TransfersApiGetTransferRequest extends imx.TransfersApiGetTransferRequest {} export interface TransfersApiListTransfersRequest extends imx.TransfersApiListTransfersRequest {} export interface UpdateCollectionRequest extends imx.UpdateCollectionRequest {} +export interface Withdrawal extends imx.Withdrawal {} export interface WithdrawalsApiGetWithdrawalRequest extends imx.WithdrawalsApiGetWithdrawalRequest {} export interface WithdrawalsApiListWithdrawalsRequest extends imx.WithdrawalsApiListWithdrawalsRequest {} diff --git a/packages/x-client/src/workflows/primarySales.ts b/packages/x-client/src/workflows/primarySales.ts index 406dfcf52c..c9c826ac2a 100644 --- a/packages/x-client/src/workflows/primarySales.ts +++ b/packages/x-client/src/workflows/primarySales.ts @@ -39,21 +39,21 @@ type RejectPrimarySaleWorkflowParams = { primarySalesApi: PrimarySalesApi; }; -type CreatePrimarySaleResponse = +export type CreatePrimarySaleResponse = | CreatePrimarySaleBadRequestBody | CreatePrimarySaleCreatedBody | CreatePrimarySaleForbiddenBody | CreatePrimarySaleUnauthorizedBody | CreatePrimarySaleNotFoundBody; -type AcceptPrimarySaleResponse = +export type AcceptPrimarySaleResponse = | AcceptPrimarySaleOKBody | AcceptPrimarySaleBadRequestBody | AcceptPrimarySaleForbiddenBody | AcceptPrimarySaleNotFoundBody | AcceptPrimarySaleUnauthorizedBody; -type RejectPrimarySaleResponse = +export type RejectPrimarySaleResponse = | RejectPrimarySaleOKBody | RejectPrimarySaleBadRequestBody | RejectPrimarySaleForbiddenBody diff --git a/packages/x-client/src/workflows/workflows.ts b/packages/x-client/src/workflows/workflows.ts index f7ea821e70..7d44bd15df 100644 --- a/packages/x-client/src/workflows/workflows.ts +++ b/packages/x-client/src/workflows/workflows.ts @@ -32,6 +32,12 @@ import { RejectPrimarySalesWorkflow, } from './primarySales'; +export type { + AcceptPrimarySaleResponse, + CreatePrimarySaleResponse, + RejectPrimarySaleResponse, +} from './primarySales'; + export class Workflows { private readonly mintsApi: MintsApi; From dab5b30537a7632ebb90e8afbf8378048778471e Mon Sep 17 00:00:00 2001 From: zaidarain1 Date: Fri, 9 Aug 2024 15:32:17 +1000 Subject: [PATCH 03/29] fix: [DX-3092] Use rollup build instead of swc d for watch mode (#2085) --- .eslintrc | 2 +- build-dependents.js | 2 +- dev.sh | 2 +- examples/passport/identity-with-nextjs/.eslintrc.json | 1 + examples/passport/next-connect-kit/.eslintrc.json | 1 + examples/passport/next-rainbow-kit/.eslintrc.json | 1 + examples/passport/next-wagmi/.eslintrc.json | 1 + examples/passport/next-web3-modal/.eslintrc.json | 1 + examples/passport/wallets-connect-with-nextjs/.eslintrc.json | 1 + examples/passport/wallets-signing-with-nextjs/.eslintrc.json | 1 + .../passport/wallets-transactions-with-nextjs/.eslintrc.json | 1 + 11 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index 197e3b9049..d0f3978f40 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,7 +13,7 @@ ], "parser": "@typescript-eslint/parser", "parserOptions": { - "project": "./tsconfig.json", + "project": "./tsconfig.base.json", "tsconfigRootDir": "." }, "rules": { diff --git a/build-dependents.js b/build-dependents.js index fb53b404a1..f61bf583d3 100755 --- a/build-dependents.js +++ b/build-dependents.js @@ -23,7 +23,7 @@ try { if (isDependent || changedProject === currentProject) { // Rebuild the current project - const command = `nx run-many --target=d --projects=${currentProject} --parallel=5`; + const command = `nx run-many --target=build --projects=${currentProject} --parallel=5`; console.log(`Running command: ${command}`); execSync(command, { stdio: 'inherit' }); diff --git a/dev.sh b/dev.sh index 44ad4a48d0..4c11ccb701 100755 --- a/dev.sh +++ b/dev.sh @@ -28,5 +28,5 @@ fi # Run nx commands with the selected or provided package name echo "Running commands for package: $PACKAGE_NAME" -nx run $PACKAGE_NAME:d --parallel=5 +nx run $PACKAGE_NAME:build --parallel=5 nx watch --all -- node ./build-dependents.js \$NX_PROJECT_NAME $(echo $PACKAGE_NAME) \ No newline at end of file diff --git a/examples/passport/identity-with-nextjs/.eslintrc.json b/examples/passport/identity-with-nextjs/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/identity-with-nextjs/.eslintrc.json +++ b/examples/passport/identity-with-nextjs/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } diff --git a/examples/passport/next-connect-kit/.eslintrc.json b/examples/passport/next-connect-kit/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/next-connect-kit/.eslintrc.json +++ b/examples/passport/next-connect-kit/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } diff --git a/examples/passport/next-rainbow-kit/.eslintrc.json b/examples/passport/next-rainbow-kit/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/next-rainbow-kit/.eslintrc.json +++ b/examples/passport/next-rainbow-kit/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } diff --git a/examples/passport/next-wagmi/.eslintrc.json b/examples/passport/next-wagmi/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/next-wagmi/.eslintrc.json +++ b/examples/passport/next-wagmi/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } diff --git a/examples/passport/next-web3-modal/.eslintrc.json b/examples/passport/next-web3-modal/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/next-web3-modal/.eslintrc.json +++ b/examples/passport/next-web3-modal/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } diff --git a/examples/passport/wallets-connect-with-nextjs/.eslintrc.json b/examples/passport/wallets-connect-with-nextjs/.eslintrc.json index 6cb73ba8c6..e7564bddde 100644 --- a/examples/passport/wallets-connect-with-nextjs/.eslintrc.json +++ b/examples/passport/wallets-connect-with-nextjs/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": ["next/core-web-vitals", "next"] } diff --git a/examples/passport/wallets-signing-with-nextjs/.eslintrc.json b/examples/passport/wallets-signing-with-nextjs/.eslintrc.json index 6cb73ba8c6..e7564bddde 100644 --- a/examples/passport/wallets-signing-with-nextjs/.eslintrc.json +++ b/examples/passport/wallets-signing-with-nextjs/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": ["next/core-web-vitals", "next"] } diff --git a/examples/passport/wallets-transactions-with-nextjs/.eslintrc.json b/examples/passport/wallets-transactions-with-nextjs/.eslintrc.json index bffb357a71..a2569c2c7c 100644 --- a/examples/passport/wallets-transactions-with-nextjs/.eslintrc.json +++ b/examples/passport/wallets-transactions-with-nextjs/.eslintrc.json @@ -1,3 +1,4 @@ { + "root": true, "extends": "next/core-web-vitals" } From 9a82d59c73b5caa504e7e5de2b2e685274053d05 Mon Sep 17 00:00:00 2001 From: "Craig M." Date: Mon, 12 Aug 2024 12:40:37 +1200 Subject: [PATCH 04/29] docs: Examples/readme updates (#2084) Co-authored-by: Matt Muscat Co-authored-by: zaidarain1 --- examples/README.md | 353 +++++++++++++++++++++++++++++---------------- 1 file changed, 231 insertions(+), 122 deletions(-) diff --git a/examples/README.md b/examples/README.md index f7d57ec1b4..139facd03b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,15 +1,75 @@ -## Contribution Guidelines +

+ + + -Important information on how to create examples, pull them through to the docs site and ensure they are covered by tests in the CI CD pipeline. +

Immutable Code Examples

+

+ Immutable's code examples as used for the code snippets in the Immutable Docs +
+ Explore the docs » +
+

+

+
-## Example Scope +**Table of Contents** -When creating an example app it should contain only examples about one particular feature to prevent overloading the example. If there are multiple ways to use the feature then it is okay to include those in one sample app. +- [Introduction](#introduction) +- [Running examples locally](#running-examples-locally) +- [Contribution guidelines](#contribution-guidelines) +- [Adding examples](#adding-examples) +- [End to end testing](#end-to-end-testing) +- [Using code examples in the docs site](#using-code-examples-in-the-docs-site) +
-For example; +# Introduction -the app in `examples/passport/wallets-connect-with-nextjs` show how to connect passport in the nextjs framework. It contains a default route that has links to each of the examples. Inside there are three routes, one for each way to connect (EIP-1193, EtherJS and Wagmi). These are okay to be part of one sample app since they show how to use one feature but using 3 different libraries. +The example apps in this examples directory are compiled and tested as part of our CI CD pipeline. The goal of this is to ensure the examples found here are always able to run against the latest version of the Immutable Typescript SDK. + +Selected portions of code from these example apps are then displayed as code snippets in our docs site, which means our code snippets in the docs are inherently always accurate as well. How to include the code from here in the docs site is explained below. + +These example apps can also be used directly as a reference and run locally to test and develop with. + +# Running examples locally + +First you need to clone or fork the `ts-immutable-sdk` repo. The examples are a part of the root workspace and running yarn install from anywhere in the workspace will install the node modules required by the examples to the root `node_modules` directory. By default, the examples pull the latest sdk version from NPM instead of building the SDK locally. + +If you want to run the examples against your local build of the SDK instead, from the project root run; + +```bash +yarn prepare:examples +``` + +and it will build the SDK first then use that build instead of what is on NPM. This is what our CI CD pipeline does to ensure it's compiling and testing the examples against the latest changes rather than what's already on NPM. + +Take a look at the README.md file of the example you want to run e.g. the [Passport Connect Readme](/examples/passport/wallets-connect-with-nextjs/README.md) + +This should include the steps required to run the example. Generally you will need to; + +1. Copy the `.env.example` file to `.env` and populate it with the environment variables as per the readme. +1. Then `yarn install` and `yarn dev` + +And the app should be served on https://localhost:3000 unless otherwise stated in the example app. + +# Contribution guidelines + +This section explains some of the core concepts for how we want to structure the examples so they can be more easily digested in the docs and by our partners. + +The goal is to have easy to read, well commented examples that focus on showing how to use a singular feature without being overly long or complicated. They should not include overly opinionated framework implementations as it can make it unclear to the reader what is required and what is optional. They should be compilable and tested with e2e tests as much as is practical. + +In the long run we want these apps to run in a code blitz frame inside the docs site much like on the [Checkout Connect Widget](https://docs.immutable.com/products/zkEVM/checkout/widgets/connect#sample-code) docs page. So aim to create an example which can be runnable like this. + +We also want to eventually index these examples and serve them in a searchable and filterable page on the docs site, so feel free to add more examples here which are not necessarily used as code snippets in the docs site. + +## Examples scope + +When creating an example app it should contain only examples about one particular feature to prevent overloading the example. If there are multiple ways to use the feature then it is okay to include those in one example app. + +For example, the [Passport Connect with NextJS](/examples/passport/wallets-connect-with-nextjs) app shows how to connect passport in the NextJS framework. + +It contains a default route that has links to each of the examples. Inside there are three routes, one for each way to connect (EIP-1193, EtherJS and Wagmi). These are okay to be part of one example app since they show how to use one feature but using 3 different libraries. If you want to show a different feature e.g signing with passport, you should create a new example app. Even though it also requires passport to connect you should not add the signing example to the connect example app. @@ -44,20 +104,57 @@ examples │ └── ... ``` -If you need to create a new example follow the steps below; +# Adding examples -## Creating a New Example +Depending on the scope of the example you're trying to add, you may be able to add it to an existing example app, or you might have to create a new example app. If you're not sure, read the [Examples Scope](#examples-scope) section above to help you decide. -create the nextjs project +If you need to add a new example or add to an existing example, please follow the [Folder Structure](#folder-structure) guidelines above. -``` +## Add to an existing example app + +The process may differ depending on how the example app is setup, but the recommendations we have made around creating a new example should follow the same structure as we've implemented for the [[Passport Connect with NextJS](/examples/passport/wallets-connect-with-nextjs) and [Passport Signing with NextJS](/examples/passport/wallets-signing-with-nextjs) examples. + +So if you need to add a new example to an existing example app you should create a branch in `ts-immutable-sdk` to add your example to and follow these steps; + +### Setup example in existing app + +1. Create new route folder inside the example app and add the `page.tsx` file. +1. Add the new route you created to the app's home page +1. Add any packages you require +1. Add any environment variables your example requires to the `.env.example` file +1. Add instructions in the `README.md` file about how to populate the `.env` file and any other build instructions. + +### Add your example + +Once you've done this you can go ahead and write your example code in the `page.tsx` file. + +You can run the example locally to test your code by following the steps in the [Running examples locally](#running-examples-locally) section. + +You will also need to create e2e tests for your example as covered in the [End to end testing](#end-to-end-testing) section. + +Creating code snippets in the docs site using your example code is covered in the [Using code examples in the docs site](#using-code-examples-in-the-docs-site) section. + +If your code example is going to be used as code snippets in the docs site, before merging your branch to main in `ts-immutable-sdk` you should follow the steps in [Using code examples in the docs site](#using-code-examples-in-the-docs-site). These steps help you to test the code snippets in the docs site before you merge your PR which avoids double handling and multiple pull requests across both repos. + +## Creating a new example app + +The process may differ if you're using a different Javascript Framework, but this assumes you will be creating a new example app using NextJS. These steps which were implemented to create the [Passport Connect](/examples/passport/wallets-connect-with-nextjs) example. It is a good reference point in terms of route structure and page layouts. If you need to copy code from there to help with your layouts then please go ahead. + +### Setup example app + +If you want to make a new NextJS app from scratch this is the process; + +Create a branch in `ts-immutable-sdk` to add your example to. + +In the console navigate to the product directory where your example will live (or create one if it doesn't exist). Then use `yarn dlx` to create the app. +```bash cd examples/ yarn dlx create-next-app@latest ``` -use the default options -``` -✔ What is your project named? -with- e.g. wallets-with-nextjs +use the default options; +```bash +✔ What is your project named? @examples//-with- e.g. @examples/passport/connect-with-nextjs ✔ Would you like to use TypeScript? … Yes ✔ Would you like to use ESLint? … Yes ✔ Would you like to use Tailwind CSS? … Yes @@ -66,162 +163,85 @@ use the default options ✔ Would you like to customize the default import alias (@/*)? No ``` -install dependencies +Install `@imtbl/sdk` and any other dependencies your example needs e.g. -``` -yarn install -``` - -install `@imtbl/sdk` and any other dependencies your example needs e.g. - -``` +```bash yarn add @imtbl/sdk yarn add @ethersproject/providers@^5.7.2 ``` -create a `.env.example` file in the root of the example. This will be committed to git so don't fill in the values +Create a `.env.example` file in the root of the example. This will be committed to git so don't fill in the values -add a template for any environment variables you need to the `.env.example` file e.g. +Add a template for any environment variables you need to the `.env.example` file e.g. -``` +```js NEXT_PUBLIC_PUBLISHABLE_KEY= NEXT_PUBLIC_CLIENT_ID= ``` -copy the `.env.example` file to `.env` in the root of the example. The `.env` file should be automatically ignored by git. - -populate any API keys and secrets e.g. - -``` -NEXT_PUBLIC_PUBLISHABLE_KEY="ABC" -NEXT_PUBLIC_CLIENT_ID="XYZ" -``` +Copy the `.env.example` file to `.env` in the root of the example (the `.env` file should be automatically ignored by git). Then populate any API keys and secrets you need to use in your application into the `.env` file. -note: variables must be prefixed with `NEXT_PUBLIC_` to be piped into the browser env. +Note: variables must be prefixed with `NEXT_PUBLIC_` to be piped into the browser env. -Update the readme with any instructions required to run the app, and include what required env variables there are with any instructions on what to populate there. +Update the readme with any instructions required to run the app, and include what required env variables there are with any instructions on what to populate there e.g. -``` +```md ## Required Environment Variables - NEXT_PUBLIC_PUBLISHABLE_KEY // replace with your publishable API key from Hub - NEXT_PUBLIC_CLIENT_ID // replace with your client ID from Hub ``` -start the project with hot reloading +Delete the any unused imports in `app/page.tsx` -``` -yarn dev -``` +Delete the contents of the return statement in `app/page.tsx` and replace with `

My Example

` or whatever you like, just render something to the screen so you can tell its working when you run the app. -check `http://localhost:3000/` in the browser to confirm it compiled and ran +Start the project with hot reloading by running; -delete the contents of `src/app/globals.css` - -delete the any unused imports in `src/app/page.tsx` +```bash +yarn dev +``` -delete the contents of the return statement in `src/app/page.tsx` and replace with `<>` +Check `http://localhost:3000/` in the browser to confirm it compiled and ran -update the title and description in `src/app/layout.tsx` to match the examples in your app e.g. +Update the title and description in `app/layout.tsx` to match the examples in your app e.g. -``` +```ts export const metadata: Metadata = { - title: "Passport Wallets Connect", + title: "Passport Connect", description: "Examples of how to connect wallets to Passport with NextJS", }; ``` -create a home page for your example app with links to all the examples in `src/app/page.tsx` - -e.g. `examples/passport/wallets-connect-with-nextjs/src/app/page.tsx` +Create a home page for your example app with links to all the examples in `src/app/page.tsx` e.g. [Passport Connect Home Page](/examples/passport/wallets-connect-with-nextjs/app/page.tsx) -create a route for each example using the naming convention `-with-` e.g. `wallets-with-etherjs` +Create a route for each example using the naming convention `-with-` e.g. `wallets-with-etherjs` -start building your examplesin the `page.tsx` in each of your example's route folders +### Add your example -e.g. `examples/passport/wallets-connect-with-nextjs/src/app/connect-with-etherjs/page.tsx` +Once you've done this you can go ahead and write your example code in the `page.tsx` file in your examples route. +You can run the example locally to test your code by following the steps in the [Running examples locally](#running-examples-locally) section. -## Creating Code Snippets +You will also need to create e2e tests for your example as covered in the [End to end testing](#end-to-end-testing) section. -In your examples find the parts of the code you want to use as code snippets and wrap them in the `#doc` and `#enddoc` comments while providing a unique label. +Creating code snippets in the docs site using your example code is covered in the [Using code examples in the docs site](#using-code-examples-in-the-docs-site) section. -Labels only have to be unique in the file, but they should be verbose so it makes it easy to know what they are e.g. +If your code example is going to be used as code snippets in the docs site, before merging your branch to main in `ts-immutable-sdk` you should follow the steps in [Using code examples in the docs site](#using-code-examples-in-the-docs-site). These steps help you to test the code snippets in the docs site before you merge your PR which avoids double handling and multiple pull requests across both repos. -e.g. `-----` - -``` -// #doc passport-wallets-nextjs-connect-eip1193-create -const passportProvider = passportInstance.connectEvm() -// #enddoc passport-wallets-nextjs-connect-eip1193-create -``` - -## Using Code Snippets in the Docs site - -It's very simple, you just add a code block with the reference to the file you want to display e.g. - -```` -```js reference=examples/passport/wallets-connect-with-nextjs/src/app/connect-with-etherjs/page.tsx title="Connect Passport to Immutable zkEVM and create the Provider" -``` -```` - -Or if you only want to display part of the file, add the `#` label of the snippet you want to display e.g. - -```` -```js reference=examples/passport/wallets-connect-with-nextjs/src/app/connect-with-etherjs/page.tsx#passport-wallets-nextjs-connect-etherjs-create title="Connect Passport to Immutable zkEVM and create the Provider" -``` -```` - -All snippets should have a title, usually this can just be the file name the snippet comes from. Don't be shy adding extra context before or after the snippet explaining any key points which are necessary. - -## Development process - -Since the docs site by default is pulling the code examples from the main branch of `ts-immutable-sdk` they will not be available until they are merged. To get around this and view the snippets in the docs site before you merge the example to main you can point the docs site to use the branch you are working on in the sdk repo while you work on them. - -Create a branch for your example in `ts-immutable-sdk` repo and a branch for your code snippets in `docs` repo. - -Create your example in your `ts-immutable-sdk` branch and push it up to GitHub. - -In your `docs` branch modify the file `/src/remark/import-code.mjs` - -Update the `BRANCH` constant from `main` to your branch name e.g. - -``` -const BRANCH = 'DVR-193-passport-signing-example'; -``` - -Now your docs branch will be pulling the code examples from your branch in `ts-immutable-sdk` and you can use them locally in your `docs` branch to make sure they make sense in the page. - -Once you're happy with your examples, make the PR for your `ts-immutable-sdk` and get it merged into main. - -Then change the `BRANCH` constant back to `main` in the `/src/remark/import-code.mjs` file. - -Now your examples are merged they will appear locally in your `docs` branch from main on `ts-immutable-sdk` and you can make any other updates you need to give the code examples context in the docs site. - -Create your PR for your `docs` branch and get it merged into main. - -### WARNING - -Do **NOT** merge your `docs` branch to main without pointing the code import back to the main branch on `ts-immutable-sdk` or it will break things when the branch is deleted and new code examples merged to main will not show in the docs site. - - -## Comments - -All examples should be heavily commented and the comments should make sense in the context the snippet is appearing in the docs site. - -## Tests +# End to end testing All examples should be covered by basic e2e tests to ensure they at least render the examples. Ideally they would also have e2e tests that prove the functionality that you're trying to show works. Depending on what you're doing in the examples, it may be difficult to e2e test certain things e.g. logging in with Passport. For this reason, testing of functionality with e2e testing is recommended if practical, but not required. Install `@playwright/test` as a dev dependency for the e2e tests. -``` +```bash yarn add -D @playwright/test ``` Create a `playwright.config.ts` file in the root of the example app and add this configuration; -``` +```ts import { defineConfig, devices } from "@playwright/test"; export default defineConfig({ @@ -258,12 +278,101 @@ Make sure you update the localhost urls `http://localhost:3000` in the above exa Create a `tests` directory in the root of the example app and start adding tests. -Example of the base level of testing required can be found in `/examples/passport/wallets-signing-with-nextjs/tests/base.spec.ts` +Example of the base level of testing required can be found in the [Passport Connect e2e Tests](/examples/passport/wallets-connect-with-nextjs/tests/base.spec.ts) spec file. Add the test runner to the scripts in your package.json -``` +```json "test": "playwright test" ``` Run your tests with `yarn test` + +# Using code examples in the docs site + +Creating and using code snippets is relatively straight forward. You can pull in a whole file or by adding some comments you can pull in just a particular few lines of a file as necessary. + +To streamline the PR process, you should create a branch in the `docs` repo to add your code snippets before your branch for the code example in `ts-immutable-sdk` is merged to main. This way we can point the docs site to your branch for the code snippets and you can see your code example in situ and make any changes required to your code example before going through the PR process. + +## Update import code branch + +In your `docs` branch modify the file `/src/remark/import-code.mjs` and update the `BRANCH` constant from `main` to the name of your branch on `ts-immutable-sdk` e.g. + +```ts +const BRANCH = 'DVR-193-passport-signing-example'; +``` + +Now your `docs` branch will be pulling the code examples from your branch in `ts-immutable-sdk` and you can use them locally in your `docs` branch to make sure they make sense in the page. + +⚠️ ⚠️ ⚠️ **IMPORTANT** ⚠️ ⚠️ ⚠️ + +Make sure to change the branch back to `main` before merging your `docs` branch or it will **BREAK** the docs site. + +## Creating code snippets + +In your code examples in `ts-immutable-sdk` find the parts of the code you want to use as code snippets and wrap them in the `#doc` and `#enddoc` comments while providing a label. + +Labels have to be unique within a file so you should use a simple naming convention to avoid clashes within the file e.g. + +e.g. `-` + +```ts +// #doc eip1193-create +const passportProvider = passportInstance.connectEvm() +// #enddoc eip1193-create +``` + +Make sure to commit and push the labels to your `ts-immutable-sdk` branch on GitHub so they can be pulled down into your `docs` local build from there. + +## Using code snippets + +It's very simple to use the code snippet in the docs site, you just add a code block with the reference to the file and the `#` of the label you want to display e.g. + +````md +```tsx reference=examples/passport/wallets-connect-with-nextjs/src/app/connect-with-eip1193/page.tsx#eip1193-create title="Create the Passport Provider" +``` +```` +Or if you want to display the whole file just don't include a `#` label at the end of the file reference e.g. + +````md +```tsx reference=examples/passport/wallets-connect-with-nextjs/src/app/connect-with-eip1193/page.tsx title="Create the Passport Provider" +``` +```` + +Just like regular code snippets, you can set language for syntax highlighting by adding it's alias directly after the opening backticks. In the above example we are setting the syntax highlighting to be for `tsx`. For more information on syntax highlighting, visit the [GitHub Documentation](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks). + +Some popular syntaxes you are likely to want to use syntax highlighting for are; + +| Language | Alias | +|------------|-------------| +| Javascript | js | +| Typescript | ts | +| Typescript with JSX | tsx +| Solidity | solidity | +| C# | csharp | +| C++ | cpp | + +For the full list of supported syntaxes and their aliases [Linguist's languages YAML file](https://github.com/github-linguist/linguist/blob/master/lib/linguist/languages.yml). + + +The other available parameters are; + +| parameter | type | description | +|------------|---------|-------------| +| reference | string | the location of the code example file in the `ts-immutable-sdk` with optional `#` label of the snippet | +| title | string | the title that will appear above the code snippet block in the docs website | +| githubLink | boolean | true by default, set to false to hide the link to file on GitHub in the header | + +Make sure the language and parameters are all set on the first line of the code snippet otherwise it will display the text as a regular inline code snippet. + +## Finishing up + +Once you're happy with your code examples on `ts-immutable-sdk` and you've tried them locally in the `docs` site from your branch on Github. Create a PR for your code examples branch in `ts-immutable-sdk` and get it merged to main. + +Now in your `docs` branch change the `BRANCH` constant in the `/src/remark/import-code.mjs` file from your branch name, back to `main`. + +You can now double check the code snippets in your `docs` branch are all pulling through correctly from main on `ts-immutable-sdk` and create the PR for your `docs` branch. + +Once your `docs` PR is merged, Netlify should automatically build and deploy the docs site. If your updates are not reflected on the docs site within 10 minutes of the PR being merged, it's likely the build has failed in Netlify. Because we are now pulling in content dynamically for the code snippets, the GET requests to fetch the code examples can sometimes randomly timeout which fails the build. + +If this happens you will need to log into the Netlify site, check the error and retry the build. Usually this will fix the deployment issue, otherwise follow up on the error message shown by Netlify. \ No newline at end of file From 58d312fb55f790eaadb4b1ab33998375ed99ae15 Mon Sep 17 00:00:00 2001 From: Naveen <116692862+naveen-imtb@users.noreply.github.com> Date: Tue, 13 Aug 2024 11:28:36 +1000 Subject: [PATCH 05/29] bugfix: TD-1577 bulk listing support with multi pop ups for smart contract wallets. (#2081) Co-authored-by: Sam Jeston --- packages/orderbook/package.json | 1 + packages/orderbook/src/orderbook.ts | 112 ++++++++++++++++-- .../orderbook/src/test/bulk-listings.e2e.ts | 17 +-- packages/orderbook/src/types.ts | 7 +- .../zkevm/step-definitions/shared.ts | 2 +- yarn.lock | 5 +- 6 files changed, 121 insertions(+), 23 deletions(-) diff --git a/packages/orderbook/package.json b/packages/orderbook/package.json index cf8713368c..527496d2f5 100644 --- a/packages/orderbook/package.json +++ b/packages/orderbook/package.json @@ -5,6 +5,7 @@ "bugs": "https://github.com/immutable/ts-immutable-sdk/issues", "dependencies": { "@imtbl/config": "0.0.0", + "@imtbl/metrics": "0.0.0", "@opensea/seaport-js": "4.0.3", "axios": "^1.6.5", "ethers": "^5.7.2", diff --git a/packages/orderbook/src/orderbook.ts b/packages/orderbook/src/orderbook.ts index 29501dd650..74b5a7e039 100644 --- a/packages/orderbook/src/orderbook.ts +++ b/packages/orderbook/src/orderbook.ts @@ -1,4 +1,5 @@ import { ModuleConfiguration } from '@imtbl/config'; +import { track } from '@imtbl/metrics'; import { ImmutableApiClient, ImmutableApiClientFactory } from './api-client'; import { getConfiguredProvider, @@ -36,7 +37,7 @@ import { PrepareBulkListingsResponse, PrepareListingResponse, SignablePurpose, - TradeResult, + TradeResult, Action, } from './types'; /** @@ -99,6 +100,11 @@ export class Orderbook { ); } + // Default order expiry to 2 years from now + static defaultOrderExpiry(): Date { + return new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 2); + } + /** * Return the configuration for the orderbook module. * @return {OrderbookModuleConfiguration} The configuration for the orderbook module. @@ -168,11 +174,16 @@ export class Orderbook { * Once the transactions are submitted and the message signed, call the completeListings method * provided in the return type with the signature. This method supports up to 20 listing creations * at a time. It can also be used for individual listings to simplify integration code paths. + * + * Bulk listings created using an EOA (Metamask) will require a single listing confirmation + * signature. + * Bulk listings creating using a smart contract wallet will require multiple listing confirmation + * signatures(as many as the number of orders). * @param {PrepareBulkListingsParams} prepareBulkListingsParams - Details about the listings * to be created. * @return {PrepareBulkListingsResponse} PrepareListingResponse includes * any unsigned approval transactions, the typed bulk order message for signing and - * the createListings method that can be called with the signature to create the listings. + * the createListings method that can be called with the signature(s) to create the listings. */ async prepareBulkListings( { @@ -185,6 +196,8 @@ export class Orderbook { throw new Error('Bulk listing creation is limited to 20 orders'); } + // Bulk listings (with single listing) code path common for both Smart contract + // wallets and EOAs. // In the event of a single order, delegate to prepareListing as the signature is more // gas efficient if (listingParams.length === 1) { @@ -193,17 +206,17 @@ export class Orderbook { listingParams[0].sell, listingParams[0].buy, new Date(), - listingParams[0].orderExpiry || new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 2), + listingParams[0].orderExpiry || Orderbook.defaultOrderExpiry(), ); return { actions: prepareListingResponse.actions, - completeListings: async (signature: string) => { + completeListings: async (signatures: string | string[]) => { const createListingResult = await this.createListing({ makerFees: listingParams[0].makerFees, orderComponents: prepareListingResponse.orderComponents, orderHash: prepareListingResponse.orderHash, - orderSignature: signature, + orderSignature: typeof signatures === 'string' ? signatures : signatures[0], }); return { @@ -217,28 +230,105 @@ export class Orderbook { }; } + // Bulk listings (with multiple listings) code path for Smart contract wallets. + // Code check to determine wallet type is not fool-proof but scenarios where smart + // contract wallet is not deployed will be an edge case + const isSmartContractWallet: boolean = await this.orderbookConfig.provider.getCode(makerAddress) !== '0x'; + if (isSmartContractWallet) { + track('orderbookmr', 'bulkListings', { walletType: 'Passport', makerAddress, listingsCount: listingParams.length }); + + // eslint-disable-next-line max-len + const prepareListingResponses = await Promise.all(listingParams.map((listing) => this.seaport.prepareSeaportOrder( + makerAddress, + listing.sell, + listing.buy, + new Date(), + listing.orderExpiry || Orderbook.defaultOrderExpiry(), + ))); + + const pendingApproval: string[] = []; + const actions = prepareListingResponses.flatMap((response) => { + // de-dupe approval transactions to ensure every contract has + // a maximum of 1 approval transaction + const dedupedActions: Action[] = []; + response.actions.forEach((action) => { + if (action.type === ActionType.TRANSACTION) { + // Assuming only a single item is on offer per listing + const contractAddress = response.orderComponents.offer[0].token; + if (!pendingApproval.includes(contractAddress)) { + pendingApproval.push(contractAddress); + dedupedActions.push(action); + } + } else { + dedupedActions.push(action); + } + }); + return dedupedActions; + }); + + return { + actions, + completeListings: async (signatures: string | string[]) => { + const signatureIsString = typeof signatures === 'string'; + if (signatureIsString) { + throw new Error('A signature per listing must be provided for smart contract wallets'); + } + + const createListingsApiResponses = await Promise.all( + prepareListingResponses.map((prepareListingResponse, i) => { + const signature = signatures[i]; + return this.apiClient.createListing({ + makerFees: listingParams[i].makerFees, + orderComponents: prepareListingResponse.orderComponents, + orderHash: prepareListingResponse.orderHash, + orderSignature: signature, + // Swallow failed creations,this gets mapped in the response to the caller as failed + }).catch(() => undefined); + }), + ); + + return { + result: createListingsApiResponses.map((apiListingResponse, i) => ({ + success: !!apiListingResponse, + orderHash: prepareListingResponses[i].orderHash, + // eslint-disable-next-line max-len + order: apiListingResponse ? mapFromOpenApiOrder(apiListingResponse.result) : undefined, + })), + }; + }, + }; + } + + // Bulk listings (with multiple listings) code path for EOA wallets. + track('orderbookmr', 'bulkListings', { walletType: 'EOA', makerAddress, listingsCount: listingParams.length }); const { actions, preparedListings } = await this.seaport.prepareBulkSeaportOrders( makerAddress, listingParams.map((orderParam) => ({ listingItem: orderParam.sell, considerationItem: orderParam.buy, orderStart: new Date(), - orderExpiry: orderParam.orderExpiry || new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 2), + orderExpiry: orderParam.orderExpiry || Orderbook.defaultOrderExpiry(), })), ); return { actions, - completeListings: async (bulkOrderSignature: string) => { + completeListings: async (signatures: string | string[]) => { + const signatureIsArray = typeof signatures === 'object'; + if (signatureIsArray && signatures.length !== 1) { + throw new Error('Only a single signature is expected for bulk listing creation'); + } + const orderComponents = preparedListings.map((orderParam) => orderParam.orderComponents); - const signatures = getBulkSeaportOrderSignatures( - bulkOrderSignature, + const signature = signatureIsArray ? signatures[0] : signatures; + const bulkOrderSignatures = getBulkSeaportOrderSignatures( + signature, orderComponents, ); const createOrdersApiListingResponse = await Promise.all( orderComponents.map((orderComponent, i) => { - const sig = signatures[i]; + const sig = bulkOrderSignatures[i]; const listing = preparedListings[i]; const listingParam = listingParams[i]; return this.apiClient.createListing({ @@ -283,7 +373,7 @@ export class Orderbook { // Default order start to now new Date(), // Default order expiry to 2 years from now - orderExpiry || new Date(Date.now() + 1000 * 60 * 60 * 24 * 365 * 2), + orderExpiry || Orderbook.defaultOrderExpiry(), ); } diff --git a/packages/orderbook/src/test/bulk-listings.e2e.ts b/packages/orderbook/src/test/bulk-listings.e2e.ts index bb0896c769..6d10582a32 100644 --- a/packages/orderbook/src/test/bulk-listings.e2e.ts +++ b/packages/orderbook/src/test/bulk-listings.e2e.ts @@ -10,6 +10,7 @@ import { waitForOrderToBeOfStatus } from './helpers/order'; import { getConfigFromEnv } from './helpers'; import { actionAll } from './helpers/actions'; import { PrepareBulkListingsParams } from '../types'; +import { GAS_OVERRIDES } from './helpers/gas'; // An array of each number between 1 and 20 const supportedListings = Array.from({ length: 20 }, (_, i) => i + 1); @@ -35,7 +36,7 @@ describe('prepareListing and createOrder bulk e2e', () => { const orderParams: PrepareBulkListingsParams['listingParams'] = []; let i = 0; while (i < numberOfListings) { - await contract.safeMint(offerer.address); + await contract.safeMint(offerer.address, GAS_OVERRIDES); orderParams.push({ buy: { @@ -56,15 +57,15 @@ describe('prepareListing and createOrder bulk e2e', () => { i++; } - await contract.safeMint(offerer.address); + await contract.safeMint(offerer.address, GAS_OVERRIDES); const { actions, completeListings } = await sdk.prepareBulkListings({ makerAddress: offerer.address, listingParams: orderParams, }); - const [bulkOrderSignature] = await actionAll(actions, offerer); - const res = await completeListings(bulkOrderSignature); + const bulkOrderSignatures = await actionAll(actions, offerer); + const res = await completeListings(bulkOrderSignatures); for (const result of res.result) { if (!result.order) { @@ -72,7 +73,7 @@ describe('prepareListing and createOrder bulk e2e', () => { } await waitForOrderToBeOfStatus(sdk, result.order.id, OrderStatusName.ACTIVE); } - }, 30_000); + }, 60_000); it('should create fail to prepare more than 20 listings', async () => { const provider = getLocalhostProvider(); @@ -95,7 +96,7 @@ describe('prepareListing and createOrder bulk e2e', () => { let i = 0; const tooManyListings = 21; while (i < tooManyListings) { - await contract.safeMint(offerer.address); + await contract.safeMint(offerer.address, GAS_OVERRIDES); orderParams.push({ buy: { @@ -113,11 +114,11 @@ describe('prepareListing and createOrder bulk e2e', () => { i++; } - await contract.safeMint(offerer.address); + await contract.safeMint(offerer.address, GAS_OVERRIDES); await expect(sdk.prepareBulkListings({ makerAddress: offerer.address, listingParams: orderParams, })).rejects.toEqual(new Error('Bulk listing creation is limited to 20 orders')); - }, 30_000); + }, 60_000); }); diff --git a/packages/orderbook/src/types.ts b/packages/orderbook/src/types.ts index 7e103390fa..d33328958b 100644 --- a/packages/orderbook/src/types.ts +++ b/packages/orderbook/src/types.ts @@ -59,7 +59,12 @@ export interface PrepareBulkListingsParams { export interface PrepareBulkListingsResponse { actions: Action[]; - completeListings: (signature: string) => Promise; + completeListings(signatures: string[]): Promise; + /** + * @deprecated Pass a string[] to `completeListings` instead to enable + * smart contract wallets + */ + completeListings(signature: string): Promise; } export interface PrepareBulkSeaportOrders { diff --git a/tests/func-tests/zkevm/step-definitions/shared.ts b/tests/func-tests/zkevm/step-definitions/shared.ts index 6a02582541..57c455df31 100644 --- a/tests/func-tests/zkevm/step-definitions/shared.ts +++ b/tests/func-tests/zkevm/step-definitions/shared.ts @@ -198,7 +198,7 @@ export const whenICreateABulkListing = ( }); const signatures = await actionAll(actions, offerer); - const { result } = await completeListings(signatures[0]); + const { result } = await completeListings(signatures); for (const res of result) { if (!res.success) { diff --git a/yarn.lock b/yarn.lock index 1cb4b81ffc..b4eec49355 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4616,6 +4616,7 @@ __metadata: resolution: "@imtbl/orderbook@workspace:packages/orderbook" dependencies: "@imtbl/config": 0.0.0 + "@imtbl/metrics": 0.0.0 "@opensea/seaport-js": 4.0.3 "@rollup/plugin-typescript": ^11.1.6 "@swc/jest": ^0.2.24 @@ -35990,7 +35991,7 @@ __metadata: resolution: "seaport-core@https://github.com/immutable/seaport-core.git#commit=0633350ec34f21fcede657ff812f11cf7d19144e" dependencies: seaport-types: ^0.0.1 - checksum: 392bce86bbfc4f7c00b65575b238825f4c696bddf5af08be7aa496862e63879375387fd4400f6e900ffee08d65c1f75cf3adad9c6c41ddcf7a3b0389cd73c3c7 + checksum: d8adba0d54106c6fe9370f0775fadef2198e5eab440b36919d1f917705ce2f0a7028e4da021b6df049aa3ca35d7e673a28b78a731130f0ff9fdf7a8bd32e3b94 languageName: node linkType: hard @@ -36034,7 +36035,7 @@ __metadata: seaport-sol: ^1.5.0 seaport-types: ^0.0.1 solady: ^0.0.84 - checksum: f31a7443a50fa1c35ec03ea031743d1d10896653ae443fa15ab8e6f5b4a2ca43f6743d523ae4e1f14df867451e5b2b2130b0bfa58a1085b0bcae3fceb8dfdc9b + checksum: a77e141e4ab5d2c4bb190a38fbb6cda3011fdf5f350b250fbeb4d82ae81cf917a966a2dcb8d9e4fd1bed29e5510ede9b15941b0ac77aeb4272dab94c9f51e7ff languageName: node linkType: hard From ab97d3c20b9f1160fef72dd3176d432bf2ab6aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=A3=20de=20Souza?= Date: Wed, 14 Aug 2024 11:11:45 +1000 Subject: [PATCH 06/29] fix: Update FAQs link (#2088) --- packages/checkout/widgets-lib/src/lib/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/checkout/widgets-lib/src/lib/constants.ts b/packages/checkout/widgets-lib/src/lib/constants.ts index e830330218..a90f7768d6 100644 --- a/packages/checkout/widgets-lib/src/lib/constants.ts +++ b/packages/checkout/widgets-lib/src/lib/constants.ts @@ -20,7 +20,7 @@ export const ETH_TOKEN_SYMBOL = 'ETH'; export const ZERO_BALANCE_STRING = '0.0'; -export const FAQS_LINK = 'https://support.immutable.com/en/'; +export const FAQS_LINK = 'https://support.immutable.com/hc/en-us/categories/9383180060815-FAQs'; /** * Delay between retries (milliseconds) From f7de60b2bea9b1d7aed56e9187a5cdfc14b5a1d6 Mon Sep 17 00:00:00 2001 From: Alejandro Loaiza Date: Wed, 14 Aug 2024 18:56:43 +1000 Subject: [PATCH 07/29] feat: Adding Wombat Wallet to whitelist of wallet connect (#2078) Co-authored-by: Jhonatan Gonzalez --- packages/checkout/widgets-lib/src/lib/walletConnect.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/checkout/widgets-lib/src/lib/walletConnect.ts b/packages/checkout/widgets-lib/src/lib/walletConnect.ts index 5c65f947fb..46383d8dfd 100644 --- a/packages/checkout/widgets-lib/src/lib/walletConnect.ts +++ b/packages/checkout/widgets-lib/src/lib/walletConnect.ts @@ -54,16 +54,17 @@ const lightThemeVariables = { '--wcm-overlay-background-color': 'rgba(255, 255, 255, 0.1)', }; -// Whitelisted wallet ids on WalletConnect explorer API +// Whitelisted wallet ids on WalletConnect explorer (https://explorer.walletconnect.com/) const metamaskId = 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96'; const frontierId = '85db431492aa2e8672e93f4ea7acf10c88b97b867b0d373107af63dc4880f041'; const ledgerLiveId = '19177a98252e07ddfc9af2083ba8e07ef627cb6103467ffebb3f8f4205fd7927'; +const wombatId = 'cb604c517064f096976972384dc89948a5c850bca9b04866a443e10171d5965d'; // const coinbaseId = 'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa'; // const phantomId = 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393'; // const rainbowId = '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369'; -const productionWalletWhitelist = [metamaskId, frontierId, ledgerLiveId]; -const sandboxWalletWhitelist = [metamaskId]; +const productionWalletWhitelist = [metamaskId, frontierId, ledgerLiveId, wombatId]; +const sandboxWalletWhitelist = [metamaskId, wombatId]; export class WalletConnectManager { private static instance: WalletConnectManager; From 7d2a65b0c13f1fdc575c3d517bd506a53b35e7c6 Mon Sep 17 00:00:00 2001 From: Naveen <116692862+naveen-imtb@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:17:22 +1000 Subject: [PATCH 08/29] chore: TD-1596: optimize use of banker funds in E2E tests. (#2091) --- tests/func-tests/zkevm/features/order.feature | 9 ++++- .../zkevm/step-definitions/order.steps.ts | 16 +++++++- .../zkevm/step-definitions/shared.ts | 39 ++++++++++++++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/tests/func-tests/zkevm/features/order.feature b/tests/func-tests/zkevm/features/order.feature index 7ce1f65fc9..b0c42034c1 100644 --- a/tests/func-tests/zkevm/features/order.feature +++ b/tests/func-tests/zkevm/features/order.feature @@ -12,6 +12,7 @@ Feature: orderbook Then the listing should be of status filled And 1 ERC721 token should be transferred to the fulfiller And 1 trade should be available + And any remaining funds are returned to the banker Scenario: bulk creating and fulfilling ERC721 listings Given I have a funded offerer account @@ -23,6 +24,7 @@ Feature: orderbook Then the listing should be of status filled And 1 ERC721 token should be transferred to the fulfiller And 1 trade should be available + And any remaining funds are returned to the banker Scenario: create and completely fill a ERC1155 listing Given I have a funded offerer account @@ -34,6 +36,7 @@ Feature: orderbook Then the listing should be of status filled And 100 ERC1155 tokens should be transferred to the fulfiller And 1 trade should be available + And any remaining funds are returned to the banker Scenario: create and partially fill a ERC1155 listing Given I have a funded offerer account @@ -50,6 +53,7 @@ Feature: orderbook # Checks for the total amount of tokens transferred - 100 = 90 from first fulfilment + 10 from second fulfilment And 100 ERC1155 tokens should be transferred to the fulfiller And 2 trades should be available + And any remaining funds are returned to the banker Scenario: create and bulk fill multiple listings Given I have a funded offerer account @@ -67,6 +71,7 @@ Feature: orderbook Then the listing should be of status active # Assert only the ERC1155 trade in this scenario And 1 trade should be available + And any remaining funds are returned to the banker Scenario: create and fully fill a ERC1155 listing without an explicit fulfill amount Given I have a funded offerer account @@ -78,6 +83,7 @@ Feature: orderbook Then the listing should be of status filled And 100 ERC1155 tokens should be transferred to the fulfiller And 1 trade should be available + And any remaining funds are returned to the banker Scenario: create and partially fill a ERC1155 listing, second fill without explicit amount Given I have a funded offerer account @@ -93,4 +99,5 @@ Feature: orderbook Then the listing should be of status filled # Checks for the total amount of tokens transferred - 100 = 90 from first fulfilment + 10 from second fulfilment And 100 ERC1155 tokens should be transferred to the fulfiller - And 2 trades should be available \ No newline at end of file + And 2 trades should be available + And any remaining funds are returned to the banker \ No newline at end of file diff --git a/tests/func-tests/zkevm/step-definitions/order.steps.ts b/tests/func-tests/zkevm/step-definitions/order.steps.ts index 16a1b46727..95ba967efc 100644 --- a/tests/func-tests/zkevm/step-definitions/order.steps.ts +++ b/tests/func-tests/zkevm/step-definitions/order.steps.ts @@ -14,7 +14,7 @@ import { whenICreateAListing, whenIFulfillTheListingToBuy, andERC1155TokensShouldBeTransferredToTheFulfiller, thenTheListingsShouldBeOfStatus, whenIFulfillBulkListings, whenIFulfillTheListingToBuyWithoutExplicitFulfillmentAmt, - whenICreateABulkListing, + whenICreateABulkListing, andAnyRemainingFundsAreReturnedToBanker, } from './shared'; const feature = loadFeature('features/order.feature', { tagFilter: process.env.TAGS }); @@ -78,6 +78,8 @@ defineFeature(feature, (test) => { andERC721TokenShouldBeTransferredToTheFulfiller(and, bankerWallet, erc721ContractAddress, testTokenId, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('bulk creating and fulfilling ERC721 listings', async ({ @@ -117,6 +119,8 @@ defineFeature(feature, (test) => { andERC721TokenShouldBeTransferredToTheFulfiller(and, bankerWallet, erc721ContractAddress, testTokenId2, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('create and completely fill a ERC1155 listing', ({ @@ -156,6 +160,8 @@ defineFeature(feature, (test) => { andERC1155TokensShouldBeTransferredToTheFulfiller(and, bankerWallet, erc1155ContractAddress, testTokenId, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('create and partially fill a ERC1155 listing', ({ @@ -203,6 +209,8 @@ defineFeature(feature, (test) => { andERC1155TokensShouldBeTransferredToTheFulfiller(and, bankerWallet, erc1155ContractAddress, testTokenId, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('create and bulk fill multiple listings', ({ @@ -256,6 +264,8 @@ defineFeature(feature, (test) => { thenTheListingShouldBeOfStatus(then, sdk, getERC1155ListingId); andTradeShouldBeAvailable(and, sdk, fulfiller, getERC1155ListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('create and fully fill a ERC1155 listing without an explicit fulfill amount', ({ @@ -294,6 +304,8 @@ defineFeature(feature, (test) => { andERC1155TokensShouldBeTransferredToTheFulfiller(and, bankerWallet, erc1155ContractAddress, testTokenId, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); test('create and partially fill a ERC1155 listing, second fill without explicit amount', ({ @@ -341,5 +353,7 @@ defineFeature(feature, (test) => { andERC1155TokensShouldBeTransferredToTheFulfiller(and, bankerWallet, erc1155ContractAddress, testTokenId, fulfiller); andTradeShouldBeAvailable(and, sdk, fulfiller, getListingId); + + andAnyRemainingFundsAreReturnedToBanker(and, bankerWallet, offerer, fulfiller); }, 120_000); }); diff --git a/tests/func-tests/zkevm/step-definitions/shared.ts b/tests/func-tests/zkevm/step-definitions/shared.ts index 57c455df31..af12739852 100644 --- a/tests/func-tests/zkevm/step-definitions/shared.ts +++ b/tests/func-tests/zkevm/step-definitions/shared.ts @@ -1,6 +1,6 @@ import { orderbook } from '@imtbl/sdk'; import { DefineStepFunction } from 'jest-cucumber'; -import { Wallet } from 'ethers'; +import { BigNumber, Wallet } from 'ethers'; import { bulkFulfillListings, connectToTestERC1155Token, @@ -14,6 +14,7 @@ import { actionAll } from '../utils/orderbook/actions'; const imxForApproval = 0.03 * 1e18; const imxForFulfillment = 0.08 * 1e18; const listingPrice = 0.0001 * 1e18; +const transferTxnFee = 0.0035 * 1e18; // Workaround to retry banker on-chain actions which can race with test runs on other PRs // eslint-disable-next-line consistent-return @@ -332,3 +333,39 @@ export const andTradeShouldBeAvailable = ( expect(targetTrades?.length === count); }); }; + +export const andAnyRemainingFundsAreReturnedToBanker = ( + and: DefineStepFunction, + banker: Wallet, + offerer: Wallet, + fulfiller: Wallet, +) => { + and(/^any remaining funds are returned to the banker$/, async () => { + await withBankerRetry(async () => { + const fulfillerBalance = await fulfiller.getBalance(); + const offererBalance = await offerer.getBalance(); + + if (fulfillerBalance.gt(BigNumber.from(transferTxnFee))) { + // fulfiller returns funds + const fulfillerReturnTxn = await fulfiller.sendTransaction({ + to: banker.address, + value: `${fulfillerBalance.sub(BigNumber.from(transferTxnFee)).toString()}`, + ...GAS_OVERRIDES, + }); + + await fulfillerReturnTxn.wait(1); + } + + if (offererBalance.gt(BigNumber.from(transferTxnFee))) { + // offerer returns funds + const offererReturnTxn = await offerer.sendTransaction({ + to: banker.address, + value: `${offererBalance.sub(BigNumber.from(transferTxnFee)).toString()}`, + ...GAS_OVERRIDES, + }); + + await offererReturnTxn.wait(1); + } + }); + }); +}; From 1f0df7281c2a3ea092b338bbb7b16d735e75f868 Mon Sep 17 00:00:00 2001 From: Jhonatan Gonzalez Date: Thu, 15 Aug 2024 13:52:22 +0800 Subject: [PATCH 09/29] Feat: [NO CHANGELOG][Checkout Widget] Add iframe permissions policy (#2092) --- .../src/postMessageHandler/postMessageHandler.ts | 10 +++++----- .../widgets/checkout/views/CheckoutAppIframe.tsx | 15 +++++++++++++++ .../src/components/ui/checkout/checkout.tsx | 5 +---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts b/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts index 7a295faf37..686094643c 100644 --- a/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts +++ b/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts @@ -31,9 +31,6 @@ export class PostMessageHandler { private logger: (...args: any[]) => void; - static isSynOrAck = (type: PostMessageHandlerEventType): boolean => type === PostMessageHandlerEventType.SYN - || type === PostMessageHandlerEventType.ACK; - constructor({ targetOrigin, eventTarget, @@ -66,11 +63,14 @@ export class PostMessageHandler { this.logger = logger; } - private handshake = (): void => { + static isSynOrAck = (type: PostMessageHandlerEventType): boolean => type === PostMessageHandlerEventType.SYN + || type === PostMessageHandlerEventType.ACK; + + protected handshake = (): void => { this.postMessage(PostMessageHandlerEventType.SYN, null); }; - private onMessage = (event: MessageEvent): void => { + protected onMessage = (event: MessageEvent): void => { if (event.origin !== this.targetOrigin) return; if (this.init) { diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx b/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx index b74f061938..07a5170a17 100644 --- a/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx +++ b/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx @@ -18,6 +18,19 @@ import { LoadingView } from '../../../views/loading/LoadingView'; import { ErrorView } from '../../../views/error/ErrorView'; import { IFRAME_INIT_TIMEOUT_MS } from '../utils/config'; +const permissions = ` + accelerometer; + camera; + microphone; + geolocation; + gyroscope; + fullscreen; + autoplay; + encrypted-media; + picture-in-picture; + clipboard-write; + clipboard-read; +`; export interface LoadingHandoverProps { text: string; duration?: number; @@ -125,6 +138,8 @@ export function CheckoutAppIframe() { ref={iframeRef} src={iframeURL} onLoad={onIframeLoad} + allow={permissions.trim().replace(/\n/g, '')} + loading="lazy" /> )} sx={{ diff --git a/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx b/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx index c04201c999..1e3df64669 100644 --- a/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx +++ b/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx @@ -58,10 +58,7 @@ function CheckoutUI() { useEffect(() => { passport.connectEvm(); checkoutWidget.mount("checkout", { - flow: CheckoutFlowType.SWAP, - amount: "0.1", - fromTokenAddress: "0x3B2d8A1931736Fc321C24864BceEe981B11c3c57", // usdc - toTokenAddress: "native", + flow: CheckoutFlowType.WALLET, }); }, []); From b0b671e3b2907c331bb2a9e5cc48cfaf32e1e2af Mon Sep 17 00:00:00 2001 From: Natalie Date: Fri, 16 Aug 2024 11:49:23 +1200 Subject: [PATCH 10/29] [DX-3122] fix: get transaction receipt success check (#2093) --- packages/game-bridge/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/game-bridge/src/index.ts b/packages/game-bridge/src/index.ts index 60927c2230..c098197185 100644 --- a/packages/game-bridge/src/index.ts +++ b/packages/game-bridge/src/index.ts @@ -716,7 +716,7 @@ window.callFunction = async (jsonData: string) => { method: 'eth_getTransactionReceipt', params: [request.txHash], }); - const success = response !== null && response !== undefined; + const success = response !== undefined; if (!success) { throw new Error('Failed to get transaction receipt'); From 549a631a18338e1beac51af4fc7709b88654e789 Mon Sep 17 00:00:00 2001 From: Ji Young Lee <641712+jiyounglee@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:18:12 +1000 Subject: [PATCH 11/29] Feat: [NO CHANGELOG][Add Funds Widget] Create Add Funds Widget by surfacing Top Up View (#2089) Co-authored-by: Mimi Tran --- .../definitions/configurations/addFunds.ts | 8 ++ .../widgets/definitions/events/addFunds.ts | 11 ++ .../src/widgets/definitions/events/index.ts | 1 + .../definitions/events/orchestration.ts | 7 ++ .../src/widgets/definitions/events/widgets.ts | 1 + .../definitions/parameters/addFunds.ts | 21 ++++ .../sdk/src/widgets/definitions/types.ts | 18 +++ .../SegmentAnalyticsProvider.ts | 1 + .../view-context/AddFundsViewContextTypes.ts | 11 ++ packages/checkout/widgets-lib/src/factory.ts | 7 ++ .../src/widgets/add-funds/AddFundsRoot.tsx | 100 ++++++++++++++++ .../src/widgets/add-funds/AddFundsWidget.tsx | 60 ++++++++++ .../widgets/add-funds/AddFundsWidgetEvents.ts | 38 ++++++ .../checkout/widgets-sample-app/src/App.tsx | 4 + .../src/components/ui/add-funds/addFunds.tsx | 108 ++++++++++++++++++ .../checkout/widgets-sample-app/src/index.tsx | 5 + 16 files changed, 401 insertions(+) create mode 100644 packages/checkout/sdk/src/widgets/definitions/configurations/addFunds.ts create mode 100644 packages/checkout/sdk/src/widgets/definitions/events/addFunds.ts create mode 100644 packages/checkout/sdk/src/widgets/definitions/parameters/addFunds.ts create mode 100644 packages/checkout/widgets-lib/src/context/view-context/AddFundsViewContextTypes.ts create mode 100644 packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx create mode 100644 packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx create mode 100644 packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidgetEvents.ts create mode 100644 packages/checkout/widgets-sample-app/src/components/ui/add-funds/addFunds.tsx diff --git a/packages/checkout/sdk/src/widgets/definitions/configurations/addFunds.ts b/packages/checkout/sdk/src/widgets/definitions/configurations/addFunds.ts new file mode 100644 index 0000000000..7e2aeff97a --- /dev/null +++ b/packages/checkout/sdk/src/widgets/definitions/configurations/addFunds.ts @@ -0,0 +1,8 @@ +import { WidgetConfiguration } from './widget'; + +/** + * Add Funds Widget Configuration represents the configuration options for the Add Funds Widget. + */ +export type AddFundsWidgetConfiguration = { +// TODO : [ADD_FUNDS] - What are the configuration needed? +} & WidgetConfiguration; diff --git a/packages/checkout/sdk/src/widgets/definitions/events/addFunds.ts b/packages/checkout/sdk/src/widgets/definitions/events/addFunds.ts new file mode 100644 index 0000000000..39a624628b --- /dev/null +++ b/packages/checkout/sdk/src/widgets/definitions/events/addFunds.ts @@ -0,0 +1,11 @@ +/** + * Enum of possible Add Funds Widget event types. + */ +export enum AddFundsEventType { + CLOSE_WIDGET = 'close-widget', + LANGUAGE_CHANGED = 'language-changed', + REQUEST_BRIDGE = 'request-bridge', + REQUEST_ONRAMP = 'request-onramp', + REQUEST_SWAP = 'request-swap', + GO_BACK = 'go-back', +} diff --git a/packages/checkout/sdk/src/widgets/definitions/events/index.ts b/packages/checkout/sdk/src/widgets/definitions/events/index.ts index 60579cdead..fecd91d320 100644 --- a/packages/checkout/sdk/src/widgets/definitions/events/index.ts +++ b/packages/checkout/sdk/src/widgets/definitions/events/index.ts @@ -7,3 +7,4 @@ export * from './bridge'; export * from './orchestration'; export * from './onramp'; export * from './checkout'; +export * from './addFunds'; diff --git a/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts b/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts index 41c48ca9e6..295e04e5de 100644 --- a/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts +++ b/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts @@ -7,6 +7,7 @@ export enum OrchestrationEventType { REQUEST_SWAP = 'request-swap', REQUEST_BRIDGE = 'request-bridge', REQUEST_ONRAMP = 'request-onramp', + REQUEST_ADD_FUNDS = 'request-add-funds', } /** @@ -66,6 +67,12 @@ export type RequestOnrampEvent = { amount: string; }; +/** + * Represents the add funds event object when the add funds widget is requested. + */ +export type RequestAddFundsEvent = { +}; + /* * Type representing the orchestration events. */ diff --git a/packages/checkout/sdk/src/widgets/definitions/events/widgets.ts b/packages/checkout/sdk/src/widgets/definitions/events/widgets.ts index e790a72a00..531a5e0d3d 100644 --- a/packages/checkout/sdk/src/widgets/definitions/events/widgets.ts +++ b/packages/checkout/sdk/src/widgets/definitions/events/widgets.ts @@ -13,6 +13,7 @@ export enum IMTBLWidgetEvents { IMTBL_ONRAMP_WIDGET_EVENT = 'imtbl-onramp-widget', IMTBL_SALE_WIDGET_EVENT = 'imtbl-sale-widget', IMTBL_CHECKOUT_WIDGET_EVENT = 'imtbl-checkout-widget', + IMTBL_ADD_FUNDS_WIDGET_EVENT = 'imtbl-add-funds-widget', } /** diff --git a/packages/checkout/sdk/src/widgets/definitions/parameters/addFunds.ts b/packages/checkout/sdk/src/widgets/definitions/parameters/addFunds.ts new file mode 100644 index 0000000000..d3f4e83bf4 --- /dev/null +++ b/packages/checkout/sdk/src/widgets/definitions/parameters/addFunds.ts @@ -0,0 +1,21 @@ +import { WidgetLanguage } from '../configurations'; + +export type AddFundsWidgetParams = { + /** The language to use for the Add Funds widget */ + language?: WidgetLanguage; + + /** Configure to show on-ramp option */ + showOnrampOption?: boolean; + + /** Configure to show swap option */ + showSwapOption?: boolean; + + /** Configure to show on bridge option */ + showBridgeOption?: boolean; + + /** Token address of the fund to be added */ + tokenAddress?: string; + + /** Amount of the fund to be added */ + amount?: string; +}; diff --git a/packages/checkout/sdk/src/widgets/definitions/types.ts b/packages/checkout/sdk/src/widgets/definitions/types.ts index 1084f6a3dd..c9e9a12d0e 100644 --- a/packages/checkout/sdk/src/widgets/definitions/types.ts +++ b/packages/checkout/sdk/src/widgets/definitions/types.ts @@ -39,6 +39,7 @@ import { CheckoutSuccessEvent, CheckoutFailureEvent, CheckoutUserActionEvent, + RequestAddFundsEvent, } from './events'; import { BridgeWidgetParams, @@ -59,6 +60,9 @@ import { CheckoutWidgetConfiguration, } from './configurations'; import { WidgetTheme } from './configurations/theme'; +import { AddFundsWidgetConfiguration } from './configurations/addFunds'; +import { AddFundsWidgetParams } from './parameters/addFunds'; +import { AddFundsEventType } from './events/addFunds'; /** * Enum representing the list of widget types. @@ -71,6 +75,7 @@ export enum WidgetType { ONRAMP = 'onramp', SALE = 'sale', CHECKOUT = 'checkout', + ADD_FUNDS = 'addFunds', } /** @@ -89,6 +94,7 @@ export type WidgetConfigurations = { [WidgetType.ONRAMP]: OnrampWidgetConfiguration; [WidgetType.SALE]: SaleWidgetConfiguration; [WidgetType.CHECKOUT]: CheckoutWidgetConfiguration; + [WidgetType.ADD_FUNDS]: AddFundsWidgetConfiguration; }; // Mapping each widget type to their parameters @@ -100,6 +106,7 @@ export type WidgetParameters = { [WidgetType.ONRAMP]: OnRampWidgetParams; [WidgetType.SALE]: SaleWidgetParams; [WidgetType.CHECKOUT]: CheckoutWidgetParams; + [WidgetType.ADD_FUNDS]: AddFundsWidgetParams; }; /** @@ -113,6 +120,7 @@ export type WidgetEventTypes = { [WidgetType.ONRAMP]: OnRampEventType | OrchestrationEventType; [WidgetType.SALE]: SaleEventType | OrchestrationEventType; [WidgetType.CHECKOUT]: CheckoutEventType | OrchestrationEventType; + [WidgetType.ADD_FUNDS]: AddFundsEventType | OrchestrationEventType; }; // Mapping of Orchestration events to their payloads @@ -122,6 +130,7 @@ type OrchestrationMapping = { [OrchestrationEventType.REQUEST_SWAP]: RequestSwapEvent; [OrchestrationEventType.REQUEST_BRIDGE]: RequestBridgeEvent; [OrchestrationEventType.REQUEST_ONRAMP]: RequestOnrampEvent; + [OrchestrationEventType.REQUEST_ADD_FUNDS]: RequestAddFundsEvent; }; type ProviderEventMapping = { @@ -196,6 +205,15 @@ export type WidgetEventData = { [CheckoutEventType.DISCONNECTED]: {}; [CheckoutEventType.USER_ACTION]: CheckoutUserActionEvent; }; + + [WidgetType.ADD_FUNDS]: { + [AddFundsEventType.CLOSE_WIDGET]: {}; + [AddFundsEventType.GO_BACK]: {}; + [AddFundsEventType.REQUEST_BRIDGE]: {}; + [AddFundsEventType.REQUEST_SWAP]: {}; + [AddFundsEventType.REQUEST_ONRAMP]: {}; + } & OrchestrationMapping & + ProviderEventMapping; }; /** diff --git a/packages/checkout/widgets-lib/src/context/analytics-provider/SegmentAnalyticsProvider.ts b/packages/checkout/widgets-lib/src/context/analytics-provider/SegmentAnalyticsProvider.ts index 9e802f3249..2edbc88583 100644 --- a/packages/checkout/widgets-lib/src/context/analytics-provider/SegmentAnalyticsProvider.ts +++ b/packages/checkout/widgets-lib/src/context/analytics-provider/SegmentAnalyticsProvider.ts @@ -11,6 +11,7 @@ export enum UserJourney { SWAP = 'Swap', BRIDGE = 'Bridge', SALE = 'PrimarySale', + ADD_FUNDS = 'AddFunds', } export type AnalyticsControlTypes = diff --git a/packages/checkout/widgets-lib/src/context/view-context/AddFundsViewContextTypes.ts b/packages/checkout/widgets-lib/src/context/view-context/AddFundsViewContextTypes.ts new file mode 100644 index 0000000000..3f42e7534c --- /dev/null +++ b/packages/checkout/widgets-lib/src/context/view-context/AddFundsViewContextTypes.ts @@ -0,0 +1,11 @@ +import { ViewType } from './ViewType'; + +export enum AddFundsWidgetViews { + ADD_FUNDS = 'ADD_FUNDS', +} + +export type AddFundsWidgetView = AddFundsView; + +interface AddFundsView extends ViewType { + type: AddFundsWidgetViews.ADD_FUNDS; +} diff --git a/packages/checkout/widgets-lib/src/factory.ts b/packages/checkout/widgets-lib/src/factory.ts index 9bb2cd36c8..c7eeb8ab80 100644 --- a/packages/checkout/widgets-lib/src/factory.ts +++ b/packages/checkout/widgets-lib/src/factory.ts @@ -23,6 +23,7 @@ import { } from './lib'; import './i18n'; import { CheckoutWidgetRoot } from './widgets/checkout/CheckoutWidgetRoot'; +import { AddFunds } from './widgets/add-funds/AddFundsRoot'; export class WidgetsFactory implements IWidgetsFactory { private sdk: Checkout; @@ -103,6 +104,12 @@ export class WidgetsFactory implements IWidgetsFactory { provider, }) as Widget as Widget; } + case WidgetType.ADD_FUNDS: { + return new AddFunds(this.sdk, { + config: { ...this.widgetConfig, ...(config) }, + provider, + }) as Widget as Widget; + } default: throw new Error('widget type not supported'); } diff --git a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx new file mode 100644 index 0000000000..aeee4dbbad --- /dev/null +++ b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx @@ -0,0 +1,100 @@ +import { + ChainId, + IMTBLWidgetEvents, + WidgetConfiguration, + WidgetProperties, + WidgetTheme, + WidgetType, +} from '@imtbl/checkout-sdk'; +import React, { Suspense } from 'react'; +import { AddFundsWidgetParams } from '@imtbl/checkout-sdk/dist/widgets/definitions/parameters/addFunds'; +import { Base } from '../BaseWidgetRoot'; +import { CustomAnalyticsProvider } from '../../context/analytics-provider/CustomAnalyticsProvider'; +import { HandoverProvider } from '../../context/handover-context/HandoverProvider'; +import i18n from '../../i18n'; +import { LoadingView } from '../../views/loading/LoadingView'; +import { ThemeProvider } from '../../components/ThemeProvider/ThemeProvider'; +import { + ConnectLoader, + ConnectLoaderParams, +} from '../../components/ConnectLoader/ConnectLoader'; +import { getL1ChainId, getL2ChainId } from '../../lib'; +import { sendAddFundsCloseEvent } from './AddFundsWidgetEvents'; + +const AddFundsWidget = React.lazy(() => import('./AddFundsWidget')); + +export class AddFunds extends Base { + protected eventTopic: IMTBLWidgetEvents = IMTBLWidgetEvents.IMTBL_ADD_FUNDS_WIDGET_EVENT; + + protected getValidatedProperties({ + config, + }: WidgetProperties): WidgetProperties { + let validatedConfig: WidgetConfiguration | undefined; + + if (config) { + validatedConfig = config; + if (config.theme === WidgetTheme.LIGHT) validatedConfig.theme = WidgetTheme.LIGHT; + else validatedConfig.theme = WidgetTheme.DARK; + } + + return { + config: validatedConfig, + }; + } + + protected getValidatedParameters( + params: AddFundsWidgetParams, + ): AddFundsWidgetParams { + const validatedParams = params; + return validatedParams; + } + + protected render() { + if (!this.reactRoot) return; + + const { t } = i18n; + const connectLoaderParams: ConnectLoaderParams = { + targetChainId: this.checkout.config.isProduction + ? ChainId.IMTBL_ZKEVM_MAINNET + : ChainId.IMTBL_ZKEVM_TESTNET, + web3Provider: this.web3Provider, + checkout: this.checkout, + allowedChains: [ + getL1ChainId(this.checkout.config), + getL2ChainId(this.checkout.config), + ], + }; + + this.reactRoot.render( + + + + + sendAddFundsCloseEvent(window)} + > + + } + > + + + + + + + , + ); + } +} diff --git a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx new file mode 100644 index 0000000000..9827f30cf7 --- /dev/null +++ b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx @@ -0,0 +1,60 @@ +import { AddFundsWidgetParams } from '@imtbl/checkout-sdk/dist/widgets/definitions/parameters/addFunds'; +import { Checkout, IMTBLWidgetEvents } from '@imtbl/checkout-sdk'; +import { Web3Provider } from '@ethersproject/providers'; +import { useContext, useMemo, useReducer } from 'react'; +import { UserJourney } from '../../context/analytics-provider/SegmentAnalyticsProvider'; +import { TopUpView } from '../../views/top-up/TopUpView'; +import { + sendAddFundsCloseEvent, + sendAddFundsGoBackEvent, +} from './AddFundsWidgetEvents'; +import { EventTargetContext } from '../../context/event-target-context/EventTargetContext'; +import { + ViewContext, + initialViewState, + viewReducer, +} from '../../context/view-context/ViewContext'; + +export type AddFundsWidgetInputs = AddFundsWidgetParams & { + checkout: Checkout; + web3Provider?: Web3Provider; +}; + +export default function AddFundsWidget({ + checkout, + web3Provider, + showOnrampOption = true, + showSwapOption = true, + showBridgeOption = true, + tokenAddress, + amount, +}: AddFundsWidgetInputs) { + const [viewState, viewDispatch] = useReducer(viewReducer, initialViewState); + + const viewReducerValues = useMemo( + () => ({ viewState, viewDispatch }), + [viewState, viewReducer], + ); + + const { + eventTargetState: { eventTarget }, + } = useContext(EventTargetContext); + + return ( + + sendAddFundsCloseEvent(eventTarget)} + onBackButtonClick={() => sendAddFundsGoBackEvent(eventTarget)} + /> + + ); +} diff --git a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidgetEvents.ts b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidgetEvents.ts new file mode 100644 index 0000000000..6f03661e54 --- /dev/null +++ b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidgetEvents.ts @@ -0,0 +1,38 @@ +import { + WidgetEvent, + WidgetType, + AddFundsEventType, + IMTBLWidgetEvents, +} from '@imtbl/checkout-sdk'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function sendAddFundsCloseEvent(eventTarget: Window | EventTarget) { + const closeWidgetEvent = new CustomEvent< + WidgetEvent + >(IMTBLWidgetEvents.IMTBL_ADD_FUNDS_WIDGET_EVENT, { + detail: { + type: AddFundsEventType.CLOSE_WIDGET, + data: {}, + }, + }); + // TODO: please remove or if necessary keep the eslint ignore + // eslint-disable-next-line no-console + console.log('close widget event:', closeWidgetEvent); + if (eventTarget !== undefined) eventTarget.dispatchEvent(closeWidgetEvent); +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function sendAddFundsGoBackEvent(eventTarget: Window | EventTarget) { + const closeWidgetEvent = new CustomEvent< + WidgetEvent + >(IMTBLWidgetEvents.IMTBL_ADD_FUNDS_WIDGET_EVENT, { + detail: { + type: AddFundsEventType.GO_BACK, + data: {}, + }, + }); + // TODO: please remove or if necessary keep the eslint ignore + // eslint-disable-next-line no-console + console.log('go back event:', closeWidgetEvent); + if (eventTarget !== undefined) eventTarget.dispatchEvent(closeWidgetEvent); +} diff --git a/packages/checkout/widgets-sample-app/src/App.tsx b/packages/checkout/widgets-sample-app/src/App.tsx index 605d251aaf..c210693a42 100644 --- a/packages/checkout/widgets-sample-app/src/App.tsx +++ b/packages/checkout/widgets-sample-app/src/App.tsx @@ -31,6 +31,10 @@ function App() { Checkout Widget
+ +
new Checkout(), []); + const factory = useMemo( + () => new WidgetsFactory(checkout,{}), + [checkout] + ); + const addFunds = useMemo( + () => factory.create(WidgetType.ADD_FUNDS, { + config: { theme: WidgetTheme.LIGHT }, + }), + [factory] + ); + const onRamp = useMemo(() => factory.create(WidgetType.ONRAMP), [factory]); + const swap = useMemo(() => factory.create(WidgetType.SWAP), [factory]); + const bridge = useMemo(() => factory.create(WidgetType.BRIDGE), [factory]); + + useEffect(() => { + addFunds.mount(ADD_FUNDS_TARGET_ID, { + showSwapOption:false, + amount: "10", + tokenAddress: "0x1CcCa691501174B4A623CeDA58cC8f1a76dc3439" + }); + addFunds.addListener(AddFundsEventType.GO_BACK, (data: any) => { + console.log("GO_BACK", data); + }); + addFunds.addListener(AddFundsEventType.CLOSE_WIDGET, (data: any) => { + console.log("CLOSE_WIDGET", data); + addFunds.unmount(); + }); + addFunds.addListener(AddFundsEventType.REQUEST_ONRAMP, (data: any) => { + console.log("REQUEST_ONRAMP", data); + addFunds.unmount(); + onRamp.addListener(OnRampEventType.CLOSE_WIDGET, (data: any) => { + console.log("CLOSE_WIDGET", data); + onRamp.unmount(); + }); + onRamp.mount(ADD_FUNDS_TARGET_ID, {}); + }); + addFunds.addListener(AddFundsEventType.REQUEST_SWAP, (data: any) => { + console.log("REQUEST_SWAP", data); + addFunds.unmount(); + swap.addListener(SwapEventType.CLOSE_WIDGET, (data: any) => { + console.log("CLOSE_WIDGET", data); + swap.unmount(); + }); + swap.mount(ADD_FUNDS_TARGET_ID, {}); + }); + addFunds.addListener(AddFundsEventType.REQUEST_BRIDGE, (data: any) => { + console.log("REQUEST_BRIDGE", data); + addFunds.unmount(); + bridge.addListener(BridgeEventType.CLOSE_WIDGET, (data: any) => { + console.log("CLOSE_WIDGET", data); + bridge.unmount(); + }); + bridge.mount(ADD_FUNDS_TARGET_ID, {}); + }); + }, [addFunds]); + + return ( +
+

Checkout Add Funds

+
+ + + + + +
+ ); +} + +export default AddFundsUI; diff --git a/packages/checkout/widgets-sample-app/src/index.tsx b/packages/checkout/widgets-sample-app/src/index.tsx index b75af754ef..b65861d01e 100644 --- a/packages/checkout/widgets-sample-app/src/index.tsx +++ b/packages/checkout/widgets-sample-app/src/index.tsx @@ -12,6 +12,7 @@ import { PassportLoginCallback } from './components/ui/marketplace-orchestrator/ import { Marketplace } from './components/ui/marketplace-orchestrator'; import { SaleUI } from './components/ui/sale/sale'; import CheckoutUI from './components/ui/checkout/checkout'; +import AddFundsUI from './components/ui/add-funds/addFunds'; const router = createBrowserRouter([ { @@ -46,6 +47,10 @@ const router = createBrowserRouter([ path: '/checkout', element: , }, + { + path: '/add-funds', + element: , + }, { path: '/marketplace-orchestrator', element: From 1eb3e786c7a1ba1fed8f53529aa12e74c2d0ab2e Mon Sep 17 00:00:00 2001 From: yundi <2666544+yundifu@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:03:01 +1000 Subject: [PATCH 12/29] fix: remove used starkex evaluation api client config (#2094) --- packages/internal/guardian/src/client/api.ts | 1 - .../client/domain/starkex-transactions-api.ts | 157 ------------------ 2 files changed, 158 deletions(-) delete mode 100644 packages/internal/guardian/src/client/domain/starkex-transactions-api.ts diff --git a/packages/internal/guardian/src/client/api.ts b/packages/internal/guardian/src/client/api.ts index 50723da672..09de3aa670 100644 --- a/packages/internal/guardian/src/client/api.ts +++ b/packages/internal/guardian/src/client/api.ts @@ -15,6 +15,5 @@ export * from './domain/messages-api'; -export * from './domain/starkex-transactions-api'; export * from './domain/transactions-api'; diff --git a/packages/internal/guardian/src/client/domain/starkex-transactions-api.ts b/packages/internal/guardian/src/client/domain/starkex-transactions-api.ts deleted file mode 100644 index 7800d5a3f5..0000000000 --- a/packages/internal/guardian/src/client/domain/starkex-transactions-api.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -/** - * Guardian - * Guardian API - * - * The version of the OpenAPI document: 1.0.0 - * Contact: support@immutable.com - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -import type { Configuration } from '../configuration'; -import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; -import globalAxios from 'axios'; -// Some imports not used depending on template conditions -// @ts-ignore -import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; -// @ts-ignore -import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; -// @ts-ignore -import type { APIError404 } from '../models'; -// @ts-ignore -import type { APIError500 } from '../models'; -// @ts-ignore -import type { TransactionEvaluationResponse } from '../models'; -/** - * StarkexTransactionsApi - axios parameter creator - * @export - */ -export const StarkexTransactionsApiAxiosParamCreator = function (configuration?: Configuration) { - return { - /** - * Check if it is a valid transaction by payload hash - * @summary Evaluate if it is an valid transaction - * @param {string} payloadHash Hash for the payload - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - evaluateStarkexTransaction: async (payloadHash: string, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'payloadHash' is not null or undefined - assertParamExists('evaluateStarkexTransaction', 'payloadHash', payloadHash) - const localVarPath = `/guardian/v1/starkex/evaluate/{payloadHash}` - .replace(`{${"payloadHash"}}`, encodeURIComponent(String(payloadHash))); - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication BearerAuth required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - } -}; - -/** - * StarkexTransactionsApi - functional programming interface - * @export - */ -export const StarkexTransactionsApiFp = function(configuration?: Configuration) { - const localVarAxiosParamCreator = StarkexTransactionsApiAxiosParamCreator(configuration) - return { - /** - * Check if it is a valid transaction by payload hash - * @summary Evaluate if it is an valid transaction - * @param {string} payloadHash Hash for the payload - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - async evaluateStarkexTransaction(payloadHash: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.evaluateStarkexTransaction(payloadHash, options); - const localVarOperationServerIndex = configuration?.serverIndex ?? 0; - const localVarOperationServerBasePath = operationServerMap['StarkexTransactionsApi.evaluateStarkexTransaction']?.[localVarOperationServerIndex]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); - }, - } -}; - -/** - * StarkexTransactionsApi - factory interface - * @export - */ -export const StarkexTransactionsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { - const localVarFp = StarkexTransactionsApiFp(configuration) - return { - /** - * Check if it is a valid transaction by payload hash - * @summary Evaluate if it is an valid transaction - * @param {StarkexTransactionsApiEvaluateStarkexTransactionRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - evaluateStarkexTransaction(requestParameters: StarkexTransactionsApiEvaluateStarkexTransactionRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.evaluateStarkexTransaction(requestParameters.payloadHash, options).then((request) => request(axios, basePath)); - }, - }; -}; - -/** - * Request parameters for evaluateStarkexTransaction operation in StarkexTransactionsApi. - * @export - * @interface StarkexTransactionsApiEvaluateStarkexTransactionRequest - */ -export interface StarkexTransactionsApiEvaluateStarkexTransactionRequest { - /** - * Hash for the payload - * @type {string} - * @memberof StarkexTransactionsApiEvaluateStarkexTransaction - */ - readonly payloadHash: string -} - -/** - * StarkexTransactionsApi - object-oriented interface - * @export - * @class StarkexTransactionsApi - * @extends {BaseAPI} - */ -export class StarkexTransactionsApi extends BaseAPI { - /** - * Check if it is a valid transaction by payload hash - * @summary Evaluate if it is an valid transaction - * @param {StarkexTransactionsApiEvaluateStarkexTransactionRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - * @memberof StarkexTransactionsApi - */ - public evaluateStarkexTransaction(requestParameters: StarkexTransactionsApiEvaluateStarkexTransactionRequest, options?: RawAxiosRequestConfig) { - return StarkexTransactionsApiFp(this.configuration).evaluateStarkexTransaction(requestParameters.payloadHash, options).then((request) => request(this.axios, this.basePath)); - } -} - From 1b94c0f1fbc07a4ba7f006b8c01e830a828605cc Mon Sep 17 00:00:00 2001 From: zaidarain1 Date: Mon, 19 Aug 2024 12:23:15 +1000 Subject: [PATCH 13/29] feat: [DX-3093] Use SRC for types and improve dev rebuild speeds (#2086) --- build-dependents.js | 2 +- dev.sh | 2 +- package.json | 1 - packages/blockchain-data/sdk/jest.config.ts | 5 +- packages/blockchain-data/sdk/package.json | 20 +- packages/blockchain-data/sdk/rollup.config.js | 5 +- packages/blockchain-data/sdk/tsconfig.json | 1 + packages/checkout/sdk-sample-app/package.json | 2 + packages/checkout/sdk/jest.config.ts | 9 +- packages/checkout/sdk/package.json | 26 ++- packages/checkout/sdk/rollup.config.js | 9 +- packages/checkout/sdk/src/index.ts | 2 + .../checkout/sdk/src/smartCheckout/buy/buy.ts | 4 +- .../widgets/definitions/parameters/index.ts | 2 + packages/checkout/sdk/tsconfig.json | 1 + packages/checkout/widgets-lib/jest.config.ts | 11 +- packages/checkout/widgets-lib/package.json | 25 +- .../checkout/widgets-lib/rollup.config.js | 8 +- .../analytics-provider/SetupAnalytics.tsx | 3 +- .../src/widgets/add-funds/AddFundsRoot.tsx | 2 +- .../src/widgets/add-funds/AddFundsWidget.tsx | 3 +- .../functions/fetchFundingBalancesUtils.ts | 5 +- packages/checkout/widgets-lib/tsconfig.json | 2 +- .../checkout/widgets-sample-app/package.json | 4 +- .../checkout/widgets-sample-app/tsconfig.json | 3 +- .../widgets-sample-app/vite.config.ts | 3 +- packages/config/jest.config.ts | 1 + packages/config/package.json | 20 +- packages/config/rollup.config.js | 5 +- packages/config/tsconfig.json | 1 + packages/game-bridge/package.json | 1 - packages/game-bridge/tsconfig.json | 1 + .../bridge/sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/internal/bridge/sdk/jest.config.ts | 4 +- packages/internal/bridge/sdk/package.json | 22 +- packages/internal/bridge/sdk/rollup.config.js | 11 +- packages/internal/bridge/sdk/tsconfig.json | 1 + packages/internal/cryptofiat/jest.config.ts | 4 +- packages/internal/cryptofiat/package.json | 21 +- packages/internal/cryptofiat/rollup.config.js | 5 +- packages/internal/cryptofiat/tsconfig.json | 1 + .../internal/dex/sdk-sample-app/package.json | 2 +- .../internal/dex/sdk-sample-app/tsconfig.json | 3 +- .../dex/sdk/{.eslintrc => .eslintrc.cjs} | 4 +- packages/internal/dex/sdk/jest.config.ts | 4 +- packages/internal/dex/sdk/package.json | 21 +- packages/internal/dex/sdk/rollup.config.js | 8 +- packages/internal/dex/sdk/tsconfig.json | 1 + packages/internal/factory/sdk/jest.config.ts | 4 +- packages/internal/factory/sdk/package.json | 20 +- .../internal/factory/sdk/rollup.config.js | 9 +- packages/internal/factory/sdk/tsconfig.json | 1 + .../internal/generated-clients/package.json | 23 +- .../generated-clients/rollup.config.js | 7 +- .../blockchain-data/domain/activities-api.ts | 12 +- .../src/blockchain-data/domain/chains-api.ts | 8 +- .../blockchain-data/domain/collections-api.ts | 20 +- .../blockchain-data/domain/metadata-api.ts | 22 +- .../blockchain-data/domain/nft-owners-api.ts | 10 +- .../src/blockchain-data/domain/nfts-api.ts | 28 +-- .../src/blockchain-data/domain/tokens-api.ts | 12 +- .../internal/generated-clients/tsconfig.json | 1 + packages/internal/guardian/package.json | 22 +- packages/internal/guardian/rollup.config.js | 10 +- packages/internal/guardian/tsconfig.json | 1 + packages/internal/metrics/package.json | 21 +- packages/internal/metrics/rollup.config.js | 7 +- packages/internal/metrics/tsconfig.json | 1 + packages/internal/toolkit/package.json | 21 +- packages/internal/toolkit/rollup.config.js | 5 +- packages/internal/toolkit/tsconfig.json | 1 + packages/minting-backend/sdk/jest.config.ts | 5 +- packages/minting-backend/sdk/package.json | 21 +- packages/minting-backend/sdk/rollup.config.js | 5 +- packages/minting-backend/sdk/tsconfig.json | 1 + packages/orderbook/package.json | 21 +- packages/orderbook/rollup.config.js | 5 +- packages/orderbook/tsconfig.json | 1 + .../passport/sdk-sample-app/next.config.js | 3 + packages/passport/sdk-sample-app/package.json | 4 +- .../NFTTransfer.tsx | 10 +- .../sdk-sample-app/tsconfig.build.json | 24 ++ .../passport/sdk-sample-app/tsconfig.json | 3 +- packages/passport/sdk/jest.config.ts | 9 +- packages/passport/sdk/package.json | 20 +- packages/passport/sdk/rollup.config.js | 5 +- packages/passport/sdk/tsconfig.json | 1 + packages/webhook/sdk/jest.config.ts | 5 +- packages/webhook/sdk/package.json | 20 +- packages/webhook/sdk/rollup.config.js | 5 +- packages/webhook/sdk/tsconfig.json | 1 + packages/x-client/jest.config.cjs | 1 + packages/x-client/package.json | 21 +- packages/x-client/rollup.config.js | 5 +- packages/x-client/src/workflows/workflows.ts | 25 +- packages/x-client/tsconfig.json | 2 +- packages/x-provider/jest.config.ts | 5 +- packages/x-provider/package.json | 21 +- packages/x-provider/rollup.config.js | 5 +- packages/x-provider/tsconfig.json | 1 + sdk/.gitignore | 1 - sdk/package.json | 3 +- sdk/rollup.config.js | 31 ++- sdk/scripts/generate-package-list.sh | 5 - sdk/scripts/updateDependencies.js | 16 +- sdk/tsconfig.json | 1 + tests/func-tests/imx/package.json | 3 - tests/func-tests/zkevm/package.json | 3 - .../zkevm/step-definitions/order.steps.ts | 2 +- tsconfig.base.json | 10 +- yarn.lock | 217 ++++++++++++------ 111 files changed, 740 insertions(+), 378 deletions(-) rename packages/internal/bridge/sdk/{.eslintrc => .eslintrc.cjs} (84%) rename packages/internal/dex/sdk/{.eslintrc => .eslintrc.cjs} (87%) create mode 100644 packages/passport/sdk-sample-app/tsconfig.build.json delete mode 100644 sdk/.gitignore delete mode 100755 sdk/scripts/generate-package-list.sh diff --git a/build-dependents.js b/build-dependents.js index f61bf583d3..fb53b404a1 100755 --- a/build-dependents.js +++ b/build-dependents.js @@ -23,7 +23,7 @@ try { if (isDependent || changedProject === currentProject) { // Rebuild the current project - const command = `nx run-many --target=build --projects=${currentProject} --parallel=5`; + const command = `nx run-many --target=d --projects=${currentProject} --parallel=5`; console.log(`Running command: ${command}`); execSync(command, { stdio: 'inherit' }); diff --git a/dev.sh b/dev.sh index 4c11ccb701..44ad4a48d0 100755 --- a/dev.sh +++ b/dev.sh @@ -28,5 +28,5 @@ fi # Run nx commands with the selected or provided package name echo "Running commands for package: $PACKAGE_NAME" -nx run $PACKAGE_NAME:build --parallel=5 +nx run $PACKAGE_NAME:d --parallel=5 nx watch --all -- node ./build-dependents.js \$NX_PROJECT_NAME $(echo $PACKAGE_NAME) \ No newline at end of file diff --git a/package.json b/package.json index 330eda0a33..37d137199f 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,6 @@ "packages/passport/sdk-sample-app", "packages/orderbook", "packages/internal/metrics", - "packages/internal/contracts", "packages/internal/toolkit", "packages/internal/cryptofiat", "packages/internal/dex/sdk", diff --git a/packages/blockchain-data/sdk/jest.config.ts b/packages/blockchain-data/sdk/jest.config.ts index c64fb9b6e6..05ef77a17a 100644 --- a/packages/blockchain-data/sdk/jest.config.ts +++ b/packages/blockchain-data/sdk/jest.config.ts @@ -4,10 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../config/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/blockchain-data/sdk/package.json b/packages/blockchain-data/sdk/package.json index 67b3ab7fcd..68f36afc65 100644 --- a/packages/blockchain-data/sdk/package.json +++ b/packages/blockchain-data/sdk/package.json @@ -25,7 +25,20 @@ "rollup": "^4.19.1", "ts-mockito": "^2.6.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" + }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } }, "homepage": "https://github.com/immutable/ts-immutable-sdk#readme", "license": "Apache-2.0", @@ -34,7 +47,7 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "generate-types": "typechain --target=ethers-v5 --out-dir=src/typechain/types 'abi/*.json'", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest", @@ -42,6 +55,5 @@ "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/blockchain-data/sdk/rollup.config.js b/packages/blockchain-data/sdk/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/blockchain-data/sdk/rollup.config.js +++ b/packages/blockchain-data/sdk/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/blockchain-data/sdk/tsconfig.json b/packages/blockchain-data/sdk/tsconfig.json index e43a0c438f..5184ceffeb 100644 --- a/packages/blockchain-data/sdk/tsconfig.json +++ b/packages/blockchain-data/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/checkout/sdk-sample-app/package.json b/packages/checkout/sdk-sample-app/package.json index 84511563c1..76d89989b7 100644 --- a/packages/checkout/sdk-sample-app/package.json +++ b/packages/checkout/sdk-sample-app/package.json @@ -18,6 +18,8 @@ "@imtbl/checkout-sdk": "0.0.0", "@imtbl/checkout-widgets": "0.0.0", "@imtbl/config": "0.0.0", + "@imtbl/orderbook": "0.0.0", + "@imtbl/passport": "0.0.0", "embla-carousel-react": "^8.1.5", "ethers": "^5.7.2", "framer-motion": "^11.0.6", diff --git a/packages/checkout/sdk/jest.config.ts b/packages/checkout/sdk/jest.config.ts index 493abbcc01..8201335503 100644 --- a/packages/checkout/sdk/jest.config.ts +++ b/packages/checkout/sdk/jest.config.ts @@ -4,14 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/bridge-sdk': '../../internal/bridge/sdk/src', - '@imtbl/config': '../../config/src', - '@imtbl/dex-sdk': '../../internal/dex/sdk/src', - '@imtbl/orderbook': '../../orderbook/src', - '@imtbl/blockchain-data': '../../blockchain-data/sdk/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'jsdom', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/checkout/sdk/package.json b/packages/checkout/sdk/package.json index ed51d66a2a..b3d7bfe772 100644 --- a/packages/checkout/sdk/package.json +++ b/packages/checkout/sdk/package.json @@ -10,6 +10,7 @@ "@imtbl/bridge-sdk": "0.0.0", "@imtbl/config": "0.0.0", "@imtbl/dex-sdk": "0.0.0", + "@imtbl/generated-clients": "0.0.0", "@imtbl/metrics": "0.0.0", "@imtbl/orderbook": "0.0.0", "@imtbl/passport": "0.0.0", @@ -29,6 +30,7 @@ "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", + "@swc/core": "^1.3.36", "@types/uuid": "^8.3.4", "babel-jest": "^29.5.0", "eslint": "^8.40.0", @@ -40,7 +42,22 @@ "text-encoding": "^0.7.0", "typedoc": "^0.26.5", "typedoc-plugin-markdown": "^4.2.3", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" + }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "module": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "module": "./dist/index.js", + "import": "./dist/index.js" + } }, "homepage": "https://github.com/immutable/ts-immutable-sdk", "keywords": [ @@ -51,9 +68,9 @@ "module": "dist/index.js", "repository": "immutable/ts-immutable-sdk.git", "scripts": { - "build": "rollup --config rollup.config.js", + "build": "NODE_ENV=production rollup --config rollup.config.js", "build:dev": "CHECKOUT_DEV_MODE=true yarn build", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "docs": "typedoc --plugin typedoc-plugin-markdown --skipErrorChecking --disableSources --out docs src/index.ts", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "lint:fix": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0 --fix", @@ -65,6 +82,5 @@ "typecheck": "tsc --noEmit" }, "source": "src/index.ts", - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/checkout/sdk/rollup.config.js b/packages/checkout/sdk/rollup.config.js index 51e6601052..b8e0150f1c 100644 --- a/packages/checkout/sdk/rollup.config.js +++ b/packages/checkout/sdk/rollup.config.js @@ -5,6 +5,9 @@ import json from '@rollup/plugin-json'; import terser from '@rollup/plugin-terser'; import replace from '@rollup/plugin-replace'; import nodePolyfills from 'rollup-plugin-polyfill-node'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; const commonPlugins = [ replace({ @@ -14,7 +17,7 @@ const commonPlugins = [ 'process.env.CHECKOUT_LOCAL_MODE': JSON.stringify(process.env.CHECKOUT_LOCAL_MODE || 'false'), 'process.versions': JSON.stringify(process.versions || {}), }), - typescript() + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup() ] export default [ @@ -38,10 +41,10 @@ export default [ context: 'window', plugins: [ json(), - nodeResolve({ browser: true }), + nodeResolve({ browser: true, exportConditions: ['browser'] }), commonjs(), nodePolyfills(), - terser(), + terser({ keep_fnames: /./ }), ...commonPlugins, ], } diff --git a/packages/checkout/sdk/src/index.ts b/packages/checkout/sdk/src/index.ts index 7b6a01091d..5e1ddf54de 100644 --- a/packages/checkout/sdk/src/index.ts +++ b/packages/checkout/sdk/src/index.ts @@ -132,9 +132,11 @@ export type { SmartCheckoutRouter, SmartCheckoutSufficient, SuccessfulGaslessCancellation, + SwapFees, SwapFundingStep, SwitchNetworkParams, SwitchNetworkResult, + TelemetryConfig, TokenAmountEstimate, TokenBalance, TokenFilter, diff --git a/packages/checkout/sdk/src/smartCheckout/buy/buy.ts b/packages/checkout/sdk/src/smartCheckout/buy/buy.ts index c4d3fd7900..4f52e5a30e 100644 --- a/packages/checkout/sdk/src/smartCheckout/buy/buy.ts +++ b/packages/checkout/sdk/src/smartCheckout/buy/buy.ts @@ -12,7 +12,7 @@ import { FulfillOrderResponse, OrderStatusName, } from '@imtbl/orderbook'; -import { GetTokenResult } from '@imtbl/generated-clients/dist/multi-rollup'; +import { mr } from '@imtbl/generated-clients'; import { track } from '@imtbl/metrics'; import * as instance from '../../instance'; import { CheckoutConfiguration, getL1ChainId, getL2ChainId } from '../../config'; @@ -158,7 +158,7 @@ export const buy = async ( const buyToken = order.result.buy[0]; if (buyToken.type === 'ERC20') { - const token = await measureAsyncExecution( + const token = await measureAsyncExecution( config, 'Time to get decimals of token contract for the buy token', blockchainClient.getToken({ contractAddress: buyToken.contractAddress, chainName: orderChainName }), diff --git a/packages/checkout/sdk/src/widgets/definitions/parameters/index.ts b/packages/checkout/sdk/src/widgets/definitions/parameters/index.ts index 1af32c0e81..69674938a7 100644 --- a/packages/checkout/sdk/src/widgets/definitions/parameters/index.ts +++ b/packages/checkout/sdk/src/widgets/definitions/parameters/index.ts @@ -1,3 +1,5 @@ +export type { AddFundsWidgetParams } from './addFunds'; + export * from './connect'; export * from './bridge'; export * from './wallet'; diff --git a/packages/checkout/sdk/tsconfig.json b/packages/checkout/sdk/tsconfig.json index dfef981dd2..186a4d5210 100644 --- a/packages/checkout/sdk/tsconfig.json +++ b/packages/checkout/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src", "test/__mocks__/window.ts"], "exclude": ["node_modules", "dist", "test"] diff --git a/packages/checkout/widgets-lib/jest.config.ts b/packages/checkout/widgets-lib/jest.config.ts index 0f08da2db4..6df7a4897f 100644 --- a/packages/checkout/widgets-lib/jest.config.ts +++ b/packages/checkout/widgets-lib/jest.config.ts @@ -4,16 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/bridge-sdk': '../../internal/bridge/sdk/src', - '@imtbl/checkout-sdk': '../sdk/src', - '@imtbl/config': '../../config/src', - '@imtbl/cryptofiat': '../../internal/cryptofiat/src', - '@imtbl/dex-sdk': '../../internal/dex/sdk/src', - '@imtbl/orderbook': '../../orderbook/src', - '@imtbl/blockchain-data': '../../blockchain-data/sdk/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'jsdom', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/checkout/widgets-lib/package.json b/packages/checkout/widgets-lib/package.json index 1a77dbf39d..0b82f9a899 100644 --- a/packages/checkout/widgets-lib/package.json +++ b/packages/checkout/widgets-lib/package.json @@ -50,6 +50,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@svgr/webpack": "^8.0.1", + "@swc/core": "^1.3.36", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -64,12 +65,28 @@ "react-app-rewired": "^2.2.1", "react-scripts": "5.0.1", "rollup": "^4.19.1", + "rollup-plugin-polyfill-node": "^0.13.0", "rollup-plugin-svg": "^2.0.0", "rollup-plugin-visualizer": "^5.12.0", "ts-jest": "^29.1.0", "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1", "web-vitals": "^2.1.4" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/main.js", + "module": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/main.js", + "module": "./dist/index.js", + "import": "./dist/index.js" + } + }, "homepage": "https://github.com/immutable/ts-immutable-sdk", "keywords": [ "immutable" @@ -79,18 +96,18 @@ "module": "dist/index.js", "private": true, "scripts": { - "build": "yarn clean && rollup --config rollup.config.js", + "build": "yarn clean && NODE_ENV=production rollup --config rollup.config.js", "build:analyse": "yarn build --plugin visualizer", "build:local": "yarn clean && yarn build && mkdir -p ../widgets-sample-app/public/lib/js && cp dist/*.js ../widgets-sample-app/public/lib/js/", "clean": "rm -rf ./dist", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "lint:fix": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0 --fix", "start": "yarn clean && NODE_ENV=development rollup --config rollup.config.js --watch", "test": "jest test --passWithNoTests", "test:watch": "jest test --passWithNoTests --watch", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --customConditions \"default\" --noEmit" }, "type": "module", - "types": "dist/index.d.ts" + "types": "./dist/index.d.ts" } diff --git a/packages/checkout/widgets-lib/rollup.config.js b/packages/checkout/widgets-lib/rollup.config.js index 3a4fe0d465..059f2cc2a8 100644 --- a/packages/checkout/widgets-lib/rollup.config.js +++ b/packages/checkout/widgets-lib/rollup.config.js @@ -2,30 +2,32 @@ import typescript from '@rollup/plugin-typescript'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; import json from '@rollup/plugin-json'; -import terser from '@rollup/plugin-terser'; import replace from '@rollup/plugin-replace'; import nodePolyfills from 'rollup-plugin-polyfill-node'; +import swc from 'unplugin-swc' const DEVELOPMENT = 'development'; const PRODUCTION = 'production'; +const isProduction = process.env.NODE_ENV === PRODUCTION + const defaultPlugins = [ json(), replace({ preventAssignment: true, 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || PRODUCTION), }), - typescript(), + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup(), ] const productionPlugins = [ resolve({ browser: true, dedupe: ['react', 'react-dom'], + exportConditions: ['default'] }), nodePolyfills(), commonjs(), - terser() ] const getPlugins = () => { diff --git a/packages/checkout/widgets-lib/src/context/analytics-provider/SetupAnalytics.tsx b/packages/checkout/widgets-lib/src/context/analytics-provider/SetupAnalytics.tsx index c1684e97ba..09e74e56e2 100644 --- a/packages/checkout/widgets-lib/src/context/analytics-provider/SetupAnalytics.tsx +++ b/packages/checkout/widgets-lib/src/context/analytics-provider/SetupAnalytics.tsx @@ -1,6 +1,5 @@ import { useCallback, useEffect } from 'react'; -import { Checkout } from '@imtbl/checkout-sdk'; -import { TelemetryConfig } from '@imtbl/checkout-sdk/dist/types'; +import { Checkout, TelemetryConfig } from '@imtbl/checkout-sdk'; import { useAnalytics } from './SegmentAnalyticsProvider'; type SetupAnalyticsProps = { diff --git a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx index aeee4dbbad..13695d73cf 100644 --- a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx +++ b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsRoot.tsx @@ -5,9 +5,9 @@ import { WidgetProperties, WidgetTheme, WidgetType, + AddFundsWidgetParams, } from '@imtbl/checkout-sdk'; import React, { Suspense } from 'react'; -import { AddFundsWidgetParams } from '@imtbl/checkout-sdk/dist/widgets/definitions/parameters/addFunds'; import { Base } from '../BaseWidgetRoot'; import { CustomAnalyticsProvider } from '../../context/analytics-provider/CustomAnalyticsProvider'; import { HandoverProvider } from '../../context/handover-context/HandoverProvider'; diff --git a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx index 9827f30cf7..47914c9453 100644 --- a/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/add-funds/AddFundsWidget.tsx @@ -1,5 +1,4 @@ -import { AddFundsWidgetParams } from '@imtbl/checkout-sdk/dist/widgets/definitions/parameters/addFunds'; -import { Checkout, IMTBLWidgetEvents } from '@imtbl/checkout-sdk'; +import { AddFundsWidgetParams, Checkout, IMTBLWidgetEvents } from '@imtbl/checkout-sdk'; import { Web3Provider } from '@ethersproject/providers'; import { useContext, useMemo, useReducer } from 'react'; import { UserJourney } from '../../context/analytics-provider/SegmentAnalyticsProvider'; diff --git a/packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalancesUtils.ts b/packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalancesUtils.ts index 4dff91564c..58d4e21350 100644 --- a/packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalancesUtils.ts +++ b/packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalancesUtils.ts @@ -9,14 +9,15 @@ import { ERC20ItemRequirement, FundingRoute, RoutingOutcomeType, + FundingStep, FundingStepType, Fee, + SwapFees, } from '@imtbl/checkout-sdk'; import { BigNumber } from 'ethers'; import { Environment } from '@imtbl/config'; import { Web3Provider } from '@ethersproject/providers'; -import { SwapFees } from '@imtbl/checkout-sdk/dist/types'; import { getTokenImageByAddress, isNativeToken } from '../../../lib/utils'; import { isGasFree } from '../../../lib/provider'; import { @@ -101,7 +102,7 @@ export const getSufficientFundingStep = ( export const getAlternativeFundingSteps = ( fundingRoutes: FundingRoute[], environment: Environment, -) => { +): FundingStep[] => { if (fundingRoutes.length === 0) { return []; } diff --git a/packages/checkout/widgets-lib/tsconfig.json b/packages/checkout/widgets-lib/tsconfig.json index fb0ee09b32..ad6a165f60 100644 --- a/packages/checkout/widgets-lib/tsconfig.json +++ b/packages/checkout/widgets-lib/tsconfig.json @@ -3,13 +3,13 @@ "compilerOptions": { "outDir": "./dist", "lib": ["dom", "dom.iterable", "esnext"], + "customConditions": ["development"], "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "jsx": "react-jsx", "noImplicitAny": false, "jsxImportSource": "@emotion/react", "experimentalDecorators": true, - "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/checkout/widgets-sample-app/package.json b/packages/checkout/widgets-sample-app/package.json index 2fc265b5c5..7cd2911ee3 100644 --- a/packages/checkout/widgets-sample-app/package.json +++ b/packages/checkout/widgets-sample-app/package.json @@ -28,6 +28,7 @@ "react-router-dom": "^6.11.0" }, "devDependencies": { + "@swc/core": "^1.3.36", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -37,13 +38,14 @@ "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^4.2.0", "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1", "vite": "^5.0.12", "vite-plugin-node-polyfills": "^0.16.0", "web-vitals": "^2.1.4" }, "private": true, "scripts": { - "build": "tsc && vite build", + "build": "tsc --customConditions \"default\" && vite build", "preview": "vite preview", "start": "vite" } diff --git a/packages/checkout/widgets-sample-app/tsconfig.json b/packages/checkout/widgets-sample-app/tsconfig.json index 5b77db70ce..cc2d5c6fd8 100644 --- a/packages/checkout/widgets-sample-app/tsconfig.json +++ b/packages/checkout/widgets-sample-app/tsconfig.json @@ -10,7 +10,8 @@ "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", + "customConditions": ["development"], "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, diff --git a/packages/checkout/widgets-sample-app/vite.config.ts b/packages/checkout/widgets-sample-app/vite.config.ts index 9b85be5081..a77b4b0abb 100644 --- a/packages/checkout/widgets-sample-app/vite.config.ts +++ b/packages/checkout/widgets-sample-app/vite.config.ts @@ -26,6 +26,7 @@ export default defineConfig({ resolve: { alias: { 'jsbi': path.resolve(__dirname, '../../../node_modules/jsbi'), - } + }, + conditions: ["default"] } }) diff --git a/packages/config/jest.config.ts b/packages/config/jest.config.ts index 33b57b1652..5a141d28a7 100644 --- a/packages/config/jest.config.ts +++ b/packages/config/jest.config.ts @@ -4,6 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], + moduleNameMapper: { '^@imtbl/(.*)$': '/../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/config/package.json b/packages/config/package.json index 9820740a60..5439016094 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -21,11 +21,24 @@ "prettier": "^2.8.7", "rollup": "^4.19.1", "ts-node": "^10.9.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -36,12 +49,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/config/rollup.config.js b/packages/config/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/config/rollup.config.js +++ b/packages/config/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/config/tsconfig.json b/packages/config/tsconfig.json index ee6d658245..5bd0b3f89e 100644 --- a/packages/config/tsconfig.json +++ b/packages/config/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/game-bridge/package.json b/packages/game-bridge/package.json index cf31c2a160..3179f705d9 100644 --- a/packages/game-bridge/package.json +++ b/packages/game-bridge/package.json @@ -16,7 +16,6 @@ "scripts": { "build": "parcel build --no-cache --no-scope-hoist", "build:local": "parcel build --no-cache --no-scope-hoist && yarn updateSdkVersion", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "start": "parcel", "updateSdkVersion": "./scripts/updateSdkVersion.sh" diff --git a/packages/game-bridge/tsconfig.json b/packages/game-bridge/tsconfig.json index 89d5c7b53d..569cb618e6 100644 --- a/packages/game-bridge/tsconfig.json +++ b/packages/game-bridge/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["dist", "jest.config.js", "node_modules"] diff --git a/packages/internal/bridge/sdk/.eslintrc b/packages/internal/bridge/sdk/.eslintrc.cjs similarity index 84% rename from packages/internal/bridge/sdk/.eslintrc rename to packages/internal/bridge/sdk/.eslintrc.cjs index 3dae7773ec..cd1f33579b 100644 --- a/packages/internal/bridge/sdk/.eslintrc +++ b/packages/internal/bridge/sdk/.eslintrc.cjs @@ -1,9 +1,9 @@ -{ +module.exports = { "extends": ["../../.eslintrc"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "max-len": [ diff --git a/packages/internal/bridge/sdk/jest.config.ts b/packages/internal/bridge/sdk/jest.config.ts index 31bd6670e8..b28e638f08 100644 --- a/packages/internal/bridge/sdk/jest.config.ts +++ b/packages/internal/bridge/sdk/jest.config.ts @@ -4,9 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../../config/src', - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../../node_modules/@imtbl/$1/src' }, verbose: true, testEnvironment: 'jsdom', transform: { diff --git a/packages/internal/bridge/sdk/package.json b/packages/internal/bridge/sdk/package.json index d172c88c8d..25539d0d82 100644 --- a/packages/internal/bridge/sdk/package.json +++ b/packages/internal/bridge/sdk/package.json @@ -27,11 +27,26 @@ "rollup": "^4.19.1", "ts-node": "^10.9.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "module": "./dist/index.browser.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "module": "./dist/index.browser.js", + "import": "./dist/index.js" + } + }, "homepage": "https://github.com/immutable/ts-immutable-sdk#readme", "keywords": [ "immutablex" @@ -43,7 +58,7 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts --max-warnings=0", "lint:fix": "cd ../../../../ && yarn wsrun -p @imtbl/bridge-sdk -c lint --fix", "test": "jest test -- --silent=false", @@ -51,6 +66,5 @@ "typecheck": "tsc --noEmit" }, "source": "src/index.ts", - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/bridge/sdk/rollup.config.js b/packages/internal/bridge/sdk/rollup.config.js index 67fbc14d3b..175501d8cd 100644 --- a/packages/internal/bridge/sdk/rollup.config.js +++ b/packages/internal/bridge/sdk/rollup.config.js @@ -2,6 +2,9 @@ import typescript from '@rollup/plugin-typescript'; import { nodeResolve } from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default [{ input: './src/index.ts', @@ -11,8 +14,8 @@ export default [{ plugins: [ json(), commonjs(), - nodeResolve(), - typescript(), + nodeResolve({ exportConditions: ["default"] }), + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup() ], }, { @@ -23,8 +26,8 @@ export default [{ plugins: [ json(), commonjs(), - nodeResolve({ browser: true }), - typescript(), + nodeResolve({ browser: true, exportConditions: ["default"] }), + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup() ], } ]; diff --git a/packages/internal/bridge/sdk/tsconfig.json b/packages/internal/bridge/sdk/tsconfig.json index c13a94c467..0644addd54 100644 --- a/packages/internal/bridge/sdk/tsconfig.json +++ b/packages/internal/bridge/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": [ "src" diff --git a/packages/internal/cryptofiat/jest.config.ts b/packages/internal/cryptofiat/jest.config.ts index f1fc16bbdd..7c27f4f311 100644 --- a/packages/internal/cryptofiat/jest.config.ts +++ b/packages/internal/cryptofiat/jest.config.ts @@ -4,9 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../config/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/internal/cryptofiat/package.json b/packages/internal/cryptofiat/package.json index 2e1e34c335..0d33b03e11 100644 --- a/packages/internal/cryptofiat/package.json +++ b/packages/internal/cryptofiat/package.json @@ -25,11 +25,24 @@ "prettier": "^2.8.7", "rollup": "^4.19.1", "ts-node": "^10.9.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -40,13 +53,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0 --fix", - "prepare": "wsrun -r build", "test": "jest", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/cryptofiat/rollup.config.js b/packages/internal/cryptofiat/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/internal/cryptofiat/rollup.config.js +++ b/packages/internal/cryptofiat/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/internal/cryptofiat/tsconfig.json b/packages/internal/cryptofiat/tsconfig.json index e43a0c438f..5184ceffeb 100644 --- a/packages/internal/cryptofiat/tsconfig.json +++ b/packages/internal/cryptofiat/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/internal/dex/sdk-sample-app/package.json b/packages/internal/dex/sdk-sample-app/package.json index 7b25953054..789d73d187 100644 --- a/packages/internal/dex/sdk-sample-app/package.json +++ b/packages/internal/dex/sdk-sample-app/package.json @@ -10,7 +10,7 @@ "concurrently": "^8.2.2", "eslint": "^8.40.0", "ethers": "^5.7.2", - "next": "13.3.1", + "next": "13.4.11", "postcss": "8.4.31", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/packages/internal/dex/sdk-sample-app/tsconfig.json b/packages/internal/dex/sdk-sample-app/tsconfig.json index 61c19abd68..07456f94d6 100644 --- a/packages/internal/dex/sdk-sample-app/tsconfig.json +++ b/packages/internal/dex/sdk-sample-app/tsconfig.json @@ -9,7 +9,8 @@ "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", + "customConditions": ["development"], "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", diff --git a/packages/internal/dex/sdk/.eslintrc b/packages/internal/dex/sdk/.eslintrc.cjs similarity index 87% rename from packages/internal/dex/sdk/.eslintrc rename to packages/internal/dex/sdk/.eslintrc.cjs index a623313d05..1177fce1bd 100644 --- a/packages/internal/dex/sdk/.eslintrc +++ b/packages/internal/dex/sdk/.eslintrc.cjs @@ -1,10 +1,10 @@ -{ +module.exports = { "extends": ["../../.eslintrc"], "ignorePatterns": ["jest.config.*", "rollup.config.*"], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json", - "tsconfigRootDir": "." + "tsconfigRootDir": __dirname }, "rules": { "implicit-arrow-linebreak": "off", diff --git a/packages/internal/dex/sdk/jest.config.ts b/packages/internal/dex/sdk/jest.config.ts index 7f5d5a76e0..25942679c5 100644 --- a/packages/internal/dex/sdk/jest.config.ts +++ b/packages/internal/dex/sdk/jest.config.ts @@ -4,9 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../../config/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../../node_modules/@imtbl/$1/src' }, verbose: true, testEnvironment: 'jsdom', transform: { diff --git a/packages/internal/dex/sdk/package.json b/packages/internal/dex/sdk/package.json index 9a30a5189d..dd7960c557 100644 --- a/packages/internal/dex/sdk/package.json +++ b/packages/internal/dex/sdk/package.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-typescript": "^11.1.6", "@swc/core": "^1.3.36", "@swc/jest": "^0.2.24", "@typechain/ethers-v5": "^10.2.0", @@ -24,11 +25,24 @@ "rollup": "^4.19.1", "ts-node": "^10.9.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -42,7 +56,7 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "generate-types": "typechain --target ethers-v5 --out-dir ./src/contracts/types ./src/contracts/ABIs/*.json", "lint": "eslint ./src --ext .ts --max-warnings=0", "lint:fix": "cd ../../../.. && yarn wsrun -p @imtbl/dex-sdk -c lint --fix", @@ -51,6 +65,5 @@ "typecheck": "tsc --noEmit" }, "source": "src/index.ts", - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/dex/sdk/rollup.config.js b/packages/internal/dex/sdk/rollup.config.js index a2756273d8..a13a9d4161 100644 --- a/packages/internal/dex/sdk/rollup.config.js +++ b/packages/internal/dex/sdk/rollup.config.js @@ -1,5 +1,8 @@ import typescript from '@rollup/plugin-typescript'; import json from '@rollup/plugin-json'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: './src/index.ts', @@ -8,8 +11,11 @@ export default { }, plugins: [ json(), + isProduction ? typescript({ + customConditions: ["default"], exclude: ['**/ABIs/*', '**/*.test.*', '**/utils/testUtils.ts'], - }), + }) : + swc.rollup({ exclude: ['**/ABIs/*', '**/*.test.*', '**/utils/testUtils.ts'] }), ], }; diff --git a/packages/internal/dex/sdk/tsconfig.json b/packages/internal/dex/sdk/tsconfig.json index 18cf2ecd20..72cb790dbb 100644 --- a/packages/internal/dex/sdk/tsconfig.json +++ b/packages/internal/dex/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/internal/factory/sdk/jest.config.ts b/packages/internal/factory/sdk/jest.config.ts index 31bd6670e8..b28e638f08 100644 --- a/packages/internal/factory/sdk/jest.config.ts +++ b/packages/internal/factory/sdk/jest.config.ts @@ -4,9 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../../config/src', - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../../node_modules/@imtbl/$1/src' }, verbose: true, testEnvironment: 'jsdom', transform: { diff --git a/packages/internal/factory/sdk/package.json b/packages/internal/factory/sdk/package.json index b54cd5d750..86a35e7c3e 100644 --- a/packages/internal/factory/sdk/package.json +++ b/packages/internal/factory/sdk/package.json @@ -24,11 +24,24 @@ "rollup": "^4.19.1", "ts-node": "^10.9.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "homepage": "https://github.com/immutable/ts-immutable-sdk#readme", "keywords": [ "immutablex" @@ -39,13 +52,12 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts --max-warnings=0", "lint:fix": "cd ../../../ && yarn wsrun -p @imtbl/factory-sdk -c lint --fix", "test": "jest test", "test:watch": "jest --watch" }, "source": "src/index.ts", - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/factory/sdk/rollup.config.js b/packages/internal/factory/sdk/rollup.config.js index 1f9bf1f17a..8b946d3e0f 100644 --- a/packages/internal/factory/sdk/rollup.config.js +++ b/packages/internal/factory/sdk/rollup.config.js @@ -2,6 +2,9 @@ import typescript from '@rollup/plugin-typescript'; import { nodeResolve } from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: './src/index.ts', @@ -11,9 +14,7 @@ export default { plugins: [ json(), commonjs(), - nodeResolve(), - typescript({ - exclude: [], - }), + nodeResolve({ exportConditions: ["default"] }), + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup() ], }; diff --git a/packages/internal/factory/sdk/tsconfig.json b/packages/internal/factory/sdk/tsconfig.json index c13a94c467..0644addd54 100644 --- a/packages/internal/factory/sdk/tsconfig.json +++ b/packages/internal/factory/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": [ "src" diff --git a/packages/internal/generated-clients/package.json b/packages/internal/generated-clients/package.json index 62e5cd3359..0ea75a7079 100644 --- a/packages/internal/generated-clients/package.json +++ b/packages/internal/generated-clients/package.json @@ -6,13 +6,28 @@ "bugs": "https://github.com/immutable/ts-immutable-sdk/issues", "devDependencies": { "@openapitools/openapi-generator-cli": "^2.13.4", + "@rollup/plugin-typescript": "^11.1.6", + "@swc/core": "^1.3.36", "jest": "^29.4.3", "rollup": "^4.19.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -23,12 +38,10 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", - "prepare": "wsrun -r build", + "d": "rollup --config rollup.config.js", "test": "jest", "typecheck": "tsc --noEmit --jsx preserve", "view-generators": "openapi-generator-cli author template -g typescript-axios -o src/templates" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/generated-clients/rollup.config.js b/packages/internal/generated-clients/rollup.config.js index 7e22038124..0269dcdc15 100644 --- a/packages/internal/generated-clients/rollup.config.js +++ b/packages/internal/generated-clients/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,7 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [ - typescript(), - ], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/activities-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/activities-api.ts index 808018af17..2f64b7644c 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/activities-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/activities-api.ts @@ -26,17 +26,17 @@ import { GetActivityResult } from '../models'; // @ts-ignore import { ListActivitiesResult } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { ActivityType } from '../models'; +export type { ActivityType } from '../models'; // @ts-ignore -export { GetActivityResult } from '../models'; +export type { GetActivityResult } from '../models'; // @ts-ignore -export { ListActivitiesResult } from '../models'; +export type { ListActivitiesResult } from '../models'; /** * Request parameters for getActivity operation in ActivitiesApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/chains-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/chains-api.ts index d44c0d5ad8..5eb89d1eb1 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/chains-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/chains-api.ts @@ -22,13 +22,13 @@ import { APIError500 } from '../models'; // @ts-ignore import { ListChainsResult } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { ListChainsResult } from '../models'; +export type { ListChainsResult } from '../models'; /** * Request parameters for listChains operation in ChainsApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/collections-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/collections-api.ts index 9b84131921..733abc88b2 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/collections-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/collections-api.ts @@ -34,25 +34,25 @@ import { RefreshCollectionMetadataRequest } from '../models'; // @ts-ignore import { RefreshCollectionMetadataResult } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError401 } from '../models'; +export type { APIError401 } from '../models'; // @ts-ignore -export { APIError403 } from '../models'; +export type { APIError403 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { AssetVerificationStatus } from '../models'; +export type { AssetVerificationStatus } from '../models'; // @ts-ignore -export { GetCollectionResult } from '../models'; +export type { GetCollectionResult } from '../models'; // @ts-ignore -export { ListCollectionsResult } from '../models'; +export type { ListCollectionsResult } from '../models'; // @ts-ignore -export { RefreshCollectionMetadataRequest } from '../models'; +export type { RefreshCollectionMetadataRequest } from '../models'; // @ts-ignore -export { RefreshCollectionMetadataResult } from '../models'; +export type { RefreshCollectionMetadataResult } from '../models'; /** * Request parameters for getCollection operation in CollectionsApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/metadata-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/metadata-api.ts index 1810a16444..eb7ca9cf37 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/metadata-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/metadata-api.ts @@ -36,27 +36,27 @@ import { RefreshMetadataByIDRequest } from '../models'; // @ts-ignore import { RefreshNFTMetadataByTokenIDRequest } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError401 } from '../models'; +export type { APIError401 } from '../models'; // @ts-ignore -export { APIError403 } from '../models'; +export type { APIError403 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError429 } from '../models'; +export type { APIError429 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { GetMetadataResult } from '../models'; +export type { GetMetadataResult } from '../models'; // @ts-ignore -export { ListMetadataResult } from '../models'; +export type { ListMetadataResult } from '../models'; // @ts-ignore -export { MetadataRefreshRateLimitResult } from '../models'; +export type { MetadataRefreshRateLimitResult } from '../models'; // @ts-ignore -export { RefreshMetadataByIDRequest } from '../models'; +export type { RefreshMetadataByIDRequest } from '../models'; // @ts-ignore -export { RefreshNFTMetadataByTokenIDRequest } from '../models'; +export type { RefreshNFTMetadataByTokenIDRequest } from '../models'; /** * Request parameters for getMetadata operation in MetadataApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/nft-owners-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/nft-owners-api.ts index f024dfbe44..157d7a7fba 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/nft-owners-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/nft-owners-api.ts @@ -24,15 +24,15 @@ import { ListCollectionOwnersResult } from '../models'; // @ts-ignore import { ListNFTOwnersResult } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { ListCollectionOwnersResult } from '../models'; +export type { ListCollectionOwnersResult } from '../models'; // @ts-ignore -export { ListNFTOwnersResult } from '../models'; +export type { ListNFTOwnersResult } from '../models'; /** * Request parameters for listAllNFTOwners operation in NftOwnersApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/nfts-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/nfts-api.ts index 200ef8db87..3ac3dbd9e2 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/nfts-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/nfts-api.ts @@ -42,33 +42,33 @@ import { ListNFTsResult } from '../models'; // @ts-ignore import { MintRequestStatus } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError401 } from '../models'; +export type { APIError401 } from '../models'; // @ts-ignore -export { APIError403 } from '../models'; +export type { APIError403 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError409 } from '../models'; +export type { APIError409 } from '../models'; // @ts-ignore -export { APIError429 } from '../models'; +export type { APIError429 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { CreateMintRequestRequest } from '../models'; +export type { CreateMintRequestRequest } from '../models'; // @ts-ignore -export { CreateMintRequestResult } from '../models'; +export type { CreateMintRequestResult } from '../models'; // @ts-ignore -export { GetNFTResult } from '../models'; +export type { GetNFTResult } from '../models'; // @ts-ignore -export { ListMintRequestsResult } from '../models'; +export type { ListMintRequestsResult } from '../models'; // @ts-ignore -export { ListNFTsByOwnerResult } from '../models'; +export type { ListNFTsByOwnerResult } from '../models'; // @ts-ignore -export { ListNFTsResult } from '../models'; +export type { ListNFTsResult } from '../models'; // @ts-ignore -export { MintRequestStatus } from '../models'; +export type { MintRequestStatus } from '../models'; /** * Request parameters for createMintRequest operation in NftsApi. diff --git a/packages/internal/generated-clients/src/blockchain-data/domain/tokens-api.ts b/packages/internal/generated-clients/src/blockchain-data/domain/tokens-api.ts index 082ca8972a..20f123327b 100644 --- a/packages/internal/generated-clients/src/blockchain-data/domain/tokens-api.ts +++ b/packages/internal/generated-clients/src/blockchain-data/domain/tokens-api.ts @@ -26,17 +26,17 @@ import { GetTokenResult } from '../models'; // @ts-ignore import { ListTokensResult } from '../models'; // @ts-ignore -export { APIError400 } from '../models'; +export type { APIError400 } from '../models'; // @ts-ignore -export { APIError404 } from '../models'; +export type { APIError404 } from '../models'; // @ts-ignore -export { APIError500 } from '../models'; +export type { APIError500 } from '../models'; // @ts-ignore -export { AssetVerificationStatus } from '../models'; +export type { AssetVerificationStatus } from '../models'; // @ts-ignore -export { GetTokenResult } from '../models'; +export type { GetTokenResult } from '../models'; // @ts-ignore -export { ListTokensResult } from '../models'; +export type { ListTokensResult } from '../models'; /** * Request parameters for getERC20Token operation in TokensApi. diff --git a/packages/internal/generated-clients/tsconfig.json b/packages/internal/generated-clients/tsconfig.json index e43a0c438f..5184ceffeb 100644 --- a/packages/internal/generated-clients/tsconfig.json +++ b/packages/internal/generated-clients/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/internal/guardian/package.json b/packages/internal/guardian/package.json index 3dd8fb8719..93a6433b17 100644 --- a/packages/internal/guardian/package.json +++ b/packages/internal/guardian/package.json @@ -9,6 +9,8 @@ }, "devDependencies": { "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-typescript": "^11.1.6", "@swc/core": "^1.3.36", "@swc/jest": "^0.2.24", "@typechain/ethers-v5": "^10.2.0", @@ -20,11 +22,24 @@ "rollup": "^4.19.1", "ts-node": "^10.9.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -38,8 +53,7 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'" + "d": "rollup --config rollup.config.js" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/guardian/rollup.config.js b/packages/internal/guardian/rollup.config.js index 64e243fc04..83edafd0f8 100644 --- a/packages/internal/guardian/rollup.config.js +++ b/packages/internal/guardian/rollup.config.js @@ -1,6 +1,9 @@ import typescript from '@rollup/plugin-typescript'; import resolve from '@rollup/plugin-node-resolve'; import json from '@rollup/plugin-json'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: './src/index.ts', @@ -9,9 +12,12 @@ export default { }, plugins: [ json(), - resolve({ browser: true }), + resolve({ browser: true, exportConditions: ["default"] }), + isProduction ? typescript({ + customConditions: ["default"], exclude: ['**/ABIs/*', '**/*.test.*', '**/utils/testUtils.ts'], - }), + }) : + swc.rollup({exclude: ['**/ABIs/*', '**/*.test.*', '**/utils/testUtils.ts']}), ], }; diff --git a/packages/internal/guardian/tsconfig.json b/packages/internal/guardian/tsconfig.json index 05087f2b94..b609792807 100644 --- a/packages/internal/guardian/tsconfig.json +++ b/packages/internal/guardian/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": [ "src" diff --git a/packages/internal/metrics/package.json b/packages/internal/metrics/package.json index f1bdd50e9b..9d9ffd4666 100644 --- a/packages/internal/metrics/package.json +++ b/packages/internal/metrics/package.json @@ -11,6 +11,7 @@ }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.6", + "@swc/core": "^1.3.36", "@swc/jest": "^0.2.24", "@types/jest": "^29.4.3", "eslint": "^8.40.0", @@ -18,11 +19,24 @@ "jest-environment-jsdom": "^29.4.3", "rollup": "^4.19.1", "ts-jest": "^29.1.0", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -32,11 +46,10 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/metrics/rollup.config.js b/packages/internal/metrics/rollup.config.js index 7e22038124..0269dcdc15 100644 --- a/packages/internal/metrics/rollup.config.js +++ b/packages/internal/metrics/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,7 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [ - typescript(), - ], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/internal/metrics/tsconfig.json b/packages/internal/metrics/tsconfig.json index f09a2d6e5c..0bbea58dc3 100644 --- a/packages/internal/metrics/tsconfig.json +++ b/packages/internal/metrics/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["dist", "jest.config.js", "node_modules"] diff --git a/packages/internal/toolkit/package.json b/packages/internal/toolkit/package.json index 760318f448..11bd2fb9eb 100644 --- a/packages/internal/toolkit/package.json +++ b/packages/internal/toolkit/package.json @@ -35,11 +35,24 @@ "prettier": "^2.8.7", "rollup": "^4.19.1", "ts-node": "^10.9.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -50,13 +63,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", - "prepare": "wsrun -r build", "test": "jest", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/internal/toolkit/rollup.config.js b/packages/internal/toolkit/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/internal/toolkit/rollup.config.js +++ b/packages/internal/toolkit/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/internal/toolkit/tsconfig.json b/packages/internal/toolkit/tsconfig.json index 0813bd4336..d8f173b231 100644 --- a/packages/internal/toolkit/tsconfig.json +++ b/packages/internal/toolkit/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist", "src/sample-app"] diff --git a/packages/minting-backend/sdk/jest.config.ts b/packages/minting-backend/sdk/jest.config.ts index c64fb9b6e6..05ef77a17a 100644 --- a/packages/minting-backend/sdk/jest.config.ts +++ b/packages/minting-backend/sdk/jest.config.ts @@ -4,10 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../config/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/minting-backend/sdk/package.json b/packages/minting-backend/sdk/package.json index d7a0469d24..624feccf5b 100644 --- a/packages/minting-backend/sdk/package.json +++ b/packages/minting-backend/sdk/package.json @@ -7,6 +7,7 @@ "dependencies": { "@imtbl/blockchain-data": "0.0.0", "@imtbl/config": "0.0.0", + "@imtbl/generated-clients": "0.0.0", "@imtbl/metrics": "0.0.0", "@imtbl/webhook": "0.0.0" }, @@ -24,7 +25,20 @@ "rollup": "^4.19.1", "testcontainers": "^10.9.0", "ts-mockito": "^2.6.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" + }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } }, "homepage": "https://github.com/immutable/ts-immutable-sdk#readme", "license": "Apache-2.0", @@ -37,12 +51,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest --passWithNoTests", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/minting-backend/sdk/rollup.config.js b/packages/minting-backend/sdk/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/minting-backend/sdk/rollup.config.js +++ b/packages/minting-backend/sdk/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/minting-backend/sdk/tsconfig.json b/packages/minting-backend/sdk/tsconfig.json index e43a0c438f..5184ceffeb 100644 --- a/packages/minting-backend/sdk/tsconfig.json +++ b/packages/minting-backend/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/orderbook/package.json b/packages/orderbook/package.json index 527496d2f5..8aa287a583 100644 --- a/packages/orderbook/package.json +++ b/packages/orderbook/package.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.6", + "@swc/core": "^1.3.36", "@swc/jest": "^0.2.24", "@typechain/ethers-v5": "^10.2.0", "@types/jest": "^29.4.3", @@ -25,7 +26,20 @@ "rollup": "^4.19.1", "ts-mockito": "^2.6.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" + }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } }, "homepage": "https://github.com/immutable/ts-immutable-sdk#readme", "license": "Apache-2.0", @@ -34,7 +48,7 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "generate-types": "typechain --target=ethers-v5 --out-dir=src/typechain/types 'abi/*.json'", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "lint:fix": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0 --fix", @@ -47,6 +61,5 @@ "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/orderbook/rollup.config.js b/packages/orderbook/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/orderbook/rollup.config.js +++ b/packages/orderbook/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/orderbook/tsconfig.json b/packages/orderbook/tsconfig.json index ee6d658245..5bd0b3f89e 100644 --- a/packages/orderbook/tsconfig.json +++ b/packages/orderbook/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/passport/sdk-sample-app/next.config.js b/packages/passport/sdk-sample-app/next.config.js index 4490769749..df318b8450 100644 --- a/packages/passport/sdk-sample-app/next.config.js +++ b/packages/passport/sdk-sample-app/next.config.js @@ -12,6 +12,9 @@ if (basePath) { /** @type {import('next').NextConfig} */ const nextConfig = { ...pathConfig, + typescript: { + tsconfigPath: './tsconfig.build.json', + }, reactStrictMode: true, }; diff --git a/packages/passport/sdk-sample-app/package.json b/packages/passport/sdk-sample-app/package.json index 2ad884d7b1..42b57164fb 100644 --- a/packages/passport/sdk-sample-app/package.json +++ b/packages/passport/sdk-sample-app/package.json @@ -6,6 +6,7 @@ "@biom3/react": "^0.25.0", "@imtbl/blockchain-data": "0.0.0", "@imtbl/config": "0.0.0", + "@imtbl/generated-clients": "0.0.0", "@imtbl/orderbook": "0.0.0", "@imtbl/passport": "0.0.0", "@imtbl/x-client": "0.0.0", @@ -16,13 +17,14 @@ "embla-carousel-react": "^8.1.5", "ethers": "^5.7.2", "framer-motion": "^11.0.6", - "next": "13.3.1", + "next": "13.4.11", "react": "^18.2.0", "react-bootstrap": "^2.7.2", "react-dom": "^18.2.0" }, "devDependencies": { "@next/eslint-plugin-next": "^13.4.7", + "@swc/core": "^1.3.36", "@types/node": "^18.14.2", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", diff --git a/packages/passport/sdk-sample-app/src/components/zkevm/EthSendTransactionExamples/NFTTransfer.tsx b/packages/passport/sdk-sample-app/src/components/zkevm/EthSendTransactionExamples/NFTTransfer.tsx index ba1aa87d5f..6f7c3a0cfa 100644 --- a/packages/passport/sdk-sample-app/src/components/zkevm/EthSendTransactionExamples/NFTTransfer.tsx +++ b/packages/passport/sdk-sample-app/src/components/zkevm/EthSendTransactionExamples/NFTTransfer.tsx @@ -11,7 +11,7 @@ import { import { EnvironmentNames, RequestExampleProps } from '@/types'; import { useImmutableProvider } from '@/context/ImmutableProvider'; import { usePassportProvider } from '@/context/PassportProvider'; -import { NFT } from '@imtbl/generated-clients/dist/blockchain-data'; +import { BlockchainData } from '@imtbl/generated-clients'; import WorkflowButton from '@/components/WorkflowButton'; import { utils } from 'ethers'; @@ -20,7 +20,7 @@ type GroupedAsset = { assets: NFTCandidate[]; }; -type NFTCandidate = NFT & { selected: boolean, to_address?: string, to_address_required?: string }; +type NFTCandidate = BlockchainData.NFT & { selected: boolean, to_address?: string, to_address_required?: string }; const chainNameMapping = (environment: EnvironmentNames) => { switch (environment) { @@ -36,7 +36,7 @@ const chainNameMapping = (environment: EnvironmentNames) => { }; function NFTTransfer({ disabled, handleExampleSubmitted }: RequestExampleProps) { - const [assets, setAssets] = useState([]); + const [assets, setAssets] = useState([]); const [transfers, setTransfers] = useState[]>([]); const [fromAddress, setFromAddress] = useState(''); const { zkEvmProvider } = usePassportProvider(); @@ -111,14 +111,14 @@ function NFTTransfer({ disabled, handleExampleSubmitted }: RequestExampleProps) }; const assetsRes = await blockchainData.listNFTsByAccountAddress(payload); - setAssets(assetsRes.result as NFT[]); + setAssets(assetsRes.result as BlockchainData.NFT[]); }; getAssets().catch(console.log); }, [blockchainData, chainName, fromAddress]); const groupedAssets = useMemo( () => assets - .reduce((group: GroupedAsset[], rawAsset: NFT) => { + .reduce((group: GroupedAsset[], rawAsset: BlockchainData.NFT) => { const sameContractAddressAssets = group.find( (g) => g.contract_address.toLowerCase() === rawAsset.contract_address.toLowerCase(), ); diff --git a/packages/passport/sdk-sample-app/tsconfig.build.json b/packages/passport/sdk-sample-app/tsconfig.build.json new file mode 100644 index 0000000000..20c737854b --- /dev/null +++ b/packages/passport/sdk-sample-app/tsconfig.build.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "customConditions": ["default"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/*": ["./src/*"], + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/packages/passport/sdk-sample-app/tsconfig.json b/packages/passport/sdk-sample-app/tsconfig.json index 0e45b9034f..5565e520a4 100644 --- a/packages/passport/sdk-sample-app/tsconfig.json +++ b/packages/passport/sdk-sample-app/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], + "customConditions": ["development"], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -9,7 +10,7 @@ "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", diff --git a/packages/passport/sdk/jest.config.ts b/packages/passport/sdk/jest.config.ts index a457a0abf9..e166d4ce55 100644 --- a/packages/passport/sdk/jest.config.ts +++ b/packages/passport/sdk/jest.config.ts @@ -4,14 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../config/src', - '@imtbl/metrics': '../../internal/metrics/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src', - '@imtbl/guardian': '../../internal/guardian/src', - '@imtbl/x-client': '../../x-client/src', - '@imtbl/toolkit': '../../internal/toolkit/src', - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'jsdom', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/passport/sdk/package.json b/packages/passport/sdk/package.json index a64bae0ffe..18fa3e0ef3 100644 --- a/packages/passport/sdk/package.json +++ b/packages/passport/sdk/package.json @@ -47,11 +47,24 @@ "prettier": "^2.8.7", "rollup": "^4.19.1", "ts-node": "^10.9.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -62,12 +75,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/passport/sdk/rollup.config.js b/packages/passport/sdk/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/passport/sdk/rollup.config.js +++ b/packages/passport/sdk/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/passport/sdk/tsconfig.json b/packages/passport/sdk/tsconfig.json index 313a445552..14daed2fa4 100644 --- a/packages/passport/sdk/tsconfig.json +++ b/packages/passport/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src", "src/types.ts"], "exclude": [ diff --git a/packages/webhook/sdk/jest.config.ts b/packages/webhook/sdk/jest.config.ts index c64fb9b6e6..05ef77a17a 100644 --- a/packages/webhook/sdk/jest.config.ts +++ b/packages/webhook/sdk/jest.config.ts @@ -4,10 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../../config/src', - '@imtbl/generated-clients': '../../internal/generated-clients/src' - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/webhook/sdk/package.json b/packages/webhook/sdk/package.json index 17a0b5ac42..63fd7fda9e 100644 --- a/packages/webhook/sdk/package.json +++ b/packages/webhook/sdk/package.json @@ -23,7 +23,20 @@ "rollup": "^4.19.1", "ts-mockito": "^2.6.1", "typechain": "^8.1.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" + }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } }, "files": [ "dist" @@ -35,13 +48,12 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "generate-types": "typechain --target=ethers-v5 --out-dir=src/typechain/types 'abi/*.json'", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest --passWithNoTests", "test:e2e": "jest --runInBand --testMatch \"**/?(*.)+(e2e).[jt]s?(x)\"", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/webhook/sdk/rollup.config.js b/packages/webhook/sdk/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/webhook/sdk/rollup.config.js +++ b/packages/webhook/sdk/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/webhook/sdk/tsconfig.json b/packages/webhook/sdk/tsconfig.json index e43a0c438f..5184ceffeb 100644 --- a/packages/webhook/sdk/tsconfig.json +++ b/packages/webhook/sdk/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist"] diff --git a/packages/x-client/jest.config.cjs b/packages/x-client/jest.config.cjs index 18296f9e01..96f065a123 100644 --- a/packages/x-client/jest.config.cjs +++ b/packages/x-client/jest.config.cjs @@ -2,6 +2,7 @@ module.exports = { testEnvironment: 'node', moduleDirectories: ['node_modules', '/src'], modulePathIgnorePatterns: ['/dist/', '/backup/'], + moduleNameMapper: { '^@imtbl/(.*)$': '/../../node_modules/@imtbl/$1/src' }, testRegex: '^.+\\.test\\.(js|ts|jsx|tsx)$', testPathIgnorePatterns: [ '/node_modules/' diff --git a/packages/x-client/package.json b/packages/x-client/package.json index e78b0e45aa..e16c0d1314 100644 --- a/packages/x-client/package.json +++ b/packages/x-client/package.json @@ -22,17 +22,31 @@ }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.6", + "@swc/core": "^1.3.36", "@swc/jest": "^0.2.24", "@types/jest": "^29.4.3", "eslint": "^8.40.0", "jest": "^29.4.3", "jest-environment-jsdom": "^29.4.3", "rollup": "^4.19.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -43,11 +57,10 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", "test": "jest", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/x-client/rollup.config.js b/packages/x-client/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/x-client/rollup.config.js +++ b/packages/x-client/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/x-client/src/workflows/workflows.ts b/packages/x-client/src/workflows/workflows.ts index 7d44bd15df..800f8be819 100644 --- a/packages/x-client/src/workflows/workflows.ts +++ b/packages/x-client/src/workflows/workflows.ts @@ -14,6 +14,13 @@ import { CreateMetadataRefreshRequest, MetadataSchemaRequest, PrimarySalesApiSignableCreatePrimarySaleRequest, + Project, + Collection, + SuccessResponse, + GetMetadataRefreshes, + GetMetadataRefreshErrorsResponse, + GetMetadataRefreshResponse, + CreateMetadataRefreshResponse, } from '../types/api'; import { UnsignedMintRequest, @@ -113,7 +120,7 @@ export class Workflows { }); } - public async getProject(ethSigner: EthSigner, id: string) { + public async getProject(ethSigner: EthSigner, id: string): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); return this.projectsApi.getProject({ @@ -126,7 +133,7 @@ export class Workflows { public async createCollection( ethSigner: EthSigner, createCollectionRequest: CreateCollectionRequest, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); return this.collectionsApi.createCollection({ @@ -140,7 +147,7 @@ export class Workflows { ethSigner: EthSigner, address: string, updateCollectionRequest: UpdateCollectionRequest, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); return this.collectionsApi.updateCollection({ @@ -155,7 +162,7 @@ export class Workflows { ethSigner: EthSigner, address: string, addMetadataSchemaToCollectionRequest: AddMetadataSchemaToCollectionRequest, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); return this.metadataApi.addMetadataSchemaToCollection({ @@ -171,7 +178,7 @@ export class Workflows { address: string, name: string, metadataSchemaRequest: MetadataSchemaRequest, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); return this.metadataApi.updateMetadataSchemaByName({ @@ -188,7 +195,7 @@ export class Workflows { collectionAddress?: string, pageSize?: number, cursor?: string, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); const ethAddress = await ethSigner.getAddress(); @@ -207,7 +214,7 @@ export class Workflows { refreshId: string, pageSize?: number, cursor?: string, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); const ethAddress = await ethSigner.getAddress(); @@ -224,7 +231,7 @@ export class Workflows { public async getMetadataRefreshResults( ethSigner: EthSigner, refreshId: string, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); const ethAddress = await ethSigner.getAddress(); @@ -239,7 +246,7 @@ export class Workflows { public async createMetadataRefresh( ethSigner: EthSigner, request: CreateMetadataRefreshRequest, - ) { + ): Promise> { const imxAuthHeaders = await generateIMXAuthorisationHeaders(ethSigner); const ethAddress = await ethSigner.getAddress(); diff --git a/packages/x-client/tsconfig.json b/packages/x-client/tsconfig.json index f42e62aedc..212fde17b0 100644 --- a/packages/x-client/tsconfig.json +++ b/packages/x-client/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], - "skipLibCheck": true + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist", "node_modules/elliptic"] diff --git a/packages/x-provider/jest.config.ts b/packages/x-provider/jest.config.ts index ca6e43f3ac..5a141d28a7 100644 --- a/packages/x-provider/jest.config.ts +++ b/packages/x-provider/jest.config.ts @@ -4,10 +4,7 @@ const config: Config = { clearMocks: true, coverageProvider: 'v8', moduleDirectories: ['node_modules', 'src'], - moduleNameMapper: { - '@imtbl/config': '../config/src', - '@imtbl/toolkit': '../internal/toolkit/src', - }, + moduleNameMapper: { '^@imtbl/(.*)$': '/../../node_modules/@imtbl/$1/src' }, testEnvironment: 'node', transform: { '^.+\\.(t|j)sx?$': '@swc/jest', diff --git a/packages/x-provider/package.json b/packages/x-provider/package.json index 39760dc8e7..fb5bff6e3a 100644 --- a/packages/x-provider/package.json +++ b/packages/x-provider/package.json @@ -33,11 +33,24 @@ "prettier": "^2.8.7", "rollup": "^4.19.1", "ts-node": "^10.9.1", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "unplugin-swc": "^1.5.1" }, "engines": { "node": ">=20.11.0" }, + "exports": { + "development": { + "types": "./src/index.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + }, + "default": { + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "import": "./dist/index.js" + } + }, "files": [ "dist" ], @@ -48,13 +61,11 @@ "repository": "immutable/ts-immutable-sdk.git", "scripts": { "build": "NODE_ENV=production rollup --config rollup.config.js", - "d": "swc src -d dist --strip-leading-paths --ignore '**/*.test.*'", + "d": "rollup --config rollup.config.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", - "prepare": "wsrun -r build", "test": "jest", "test:watch": "jest --watch", "typecheck": "tsc --noEmit --jsx preserve" }, - "type": "module", - "types": "dist/index.d.ts" + "type": "module" } diff --git a/packages/x-provider/rollup.config.js b/packages/x-provider/rollup.config.js index 16a7d58d7e..0269dcdc15 100644 --- a/packages/x-provider/rollup.config.js +++ b/packages/x-provider/rollup.config.js @@ -1,4 +1,7 @@ import typescript from '@rollup/plugin-typescript'; +import swc from 'unplugin-swc' + +const isProduction = process.env.NODE_ENV === 'production'; export default { input: 'src/index.ts', @@ -6,5 +9,5 @@ export default { dir: 'dist', format: 'es', }, - plugins: [typescript()], + plugins: [isProduction ? typescript({customConditions: ["default"]}) : swc.rollup()], }; diff --git a/packages/x-provider/tsconfig.json b/packages/x-provider/tsconfig.json index 6d8bc46f04..a61b882cee 100644 --- a/packages/x-provider/tsconfig.json +++ b/packages/x-provider/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "outDir": "./dist", "rootDirs": ["src"], + "customConditions": ["development"] }, "include": ["src"], "exclude": ["node_modules", "dist", "src/sample-app"] diff --git a/sdk/.gitignore b/sdk/.gitignore deleted file mode 100644 index 44803ff59f..0000000000 --- a/sdk/.gitignore +++ /dev/null @@ -1 +0,0 @@ -workspace-packages.json \ No newline at end of file diff --git a/sdk/package.json b/sdk/package.json index b6ff70fb86..da6c49b339 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -161,10 +161,9 @@ "copyBrowserBundles": "node scripts/copyBrowserBundles.js", "generateIndex": "node scripts/generateIndex.js", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", - "packageList": "./scripts/generate-package-list.sh", "regenModules": "yarn generateIndex && yarn updateExports", "typecheck": "tsc --noEmit --jsx preserve", - "updateDependencies": "yarn packageList && node ./scripts/updateDependencies.js && yarn syncpack:format", + "updateDependencies": "node ./scripts/updateDependencies.js && yarn run --top-level syncpack:format", "updateExports": "node scripts/updateExports.js" }, "type": "module", diff --git a/sdk/rollup.config.js b/sdk/rollup.config.js index 198add415c..17bb09849b 100644 --- a/sdk/rollup.config.js +++ b/sdk/rollup.config.js @@ -1,6 +1,6 @@ import typescript from '@rollup/plugin-typescript'; import { nodeResolve } from '@rollup/plugin-node-resolve'; -import { readFileSync } from 'fs'; +import { execSync } from 'child_process'; import commonJs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import dts from 'rollup-plugin-dts'; @@ -11,23 +11,15 @@ import terser from '@rollup/plugin-terser'; import nodePolyfills from 'rollup-plugin-polyfill-node'; import babel from '@rollup/plugin-babel'; -import { fileURLToPath } from 'url'; -import { dirname, join } from 'path'; - -// Convert the import.meta.url to a file path -const __filename = fileURLToPath(import.meta.url); -// Get the directory name of the current module -const __dirname = dirname(__filename); -const projectRoot = __dirname; - // RELEASE_TYPE environment variable is set by the CI/CD pipeline const releaseType = process.env.RELEASE_TYPE || 'alpha'; -const packages = JSON.parse( - readFileSync(join(projectRoot, 'workspace-packages.json'), { encoding: 'utf8' } -)); - -const getPackages = () => packages.map((pkg) => pkg.name); +const packages = execSync('yarn workspaces list --json') + .toString() + .trim() + .split('\n') + .map((line) => JSON.parse(line)) + .map((pkg) => pkg.name); // Get relevant files to bundle const getFilesToBuild = () => { @@ -61,7 +53,8 @@ const buildJS = () => { }, plugins: [ nodeResolve({ - resolveOnly: getPackages(), + resolveOnly: packages, + exportConditions: ["default"], }), json(), commonJs(), @@ -114,7 +107,8 @@ export default [ }, plugins: [ nodeResolve({ - resolveOnly: getPackages(), + resolveOnly: packages, + exportConditions: ["default"] }), json(), commonJs(), @@ -141,6 +135,7 @@ export default [ main: true, browser: true, preferBuiltins: false, + exportConditions: ["default"], }), nodePolyfills(), json(), @@ -161,7 +156,7 @@ export default [ 'process.env.NODE_ENV': '"production"', 'process': 'undefined' }), - terser(), + terser({ keep_fnames: /./ }), ], }, diff --git a/sdk/scripts/generate-package-list.sh b/sdk/scripts/generate-package-list.sh deleted file mode 100755 index 71c90ba0d6..0000000000 --- a/sdk/scripts/generate-package-list.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -set -e - -yarn workspaces list --json | sed -e ' $ ! s/}/},/' | sed '$ s/$/]/' | sed '1 s/^/[/' > workspace-packages.json \ No newline at end of file diff --git a/sdk/scripts/updateDependencies.js b/sdk/scripts/updateDependencies.js index 1544fed536..13c366b0fd 100644 --- a/sdk/scripts/updateDependencies.js +++ b/sdk/scripts/updateDependencies.js @@ -4,19 +4,17 @@ import { Configuration, Project } from '@yarnpkg/core'; import semver from 'semver'; import fs from 'fs'; import path from 'path'; +import { execSync } from 'child_process'; const __dirname = path.resolve(); const SDK_PACKAGE = '@imtbl/sdk'; -const getWorkspacePackages = () => { - const workspacePackages = JSON.parse( - fs.readFileSync(path.resolve(__dirname, 'workspace-packages.json'), { - encoding: 'utf8', - }) - ).map((pkg) => pkg.name); - return workspacePackages; -}; -const workspacePackages = getWorkspacePackages(); +const workspacePackages = execSync('yarn workspaces list --json') + .toString() + .trim() + .split('\n') + .map((line) => JSON.parse(line)) + .map((pkg) => pkg.name); // Update the map with the dependency if it doesn't exist, or if the // version is greater than the existing version diff --git a/sdk/tsconfig.json b/sdk/tsconfig.json index 30f13daf53..d8730a79e3 100644 --- a/sdk/tsconfig.json +++ b/sdk/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { + "customConditions": ["default"], "outDir": "./dist", "rootDirs": ["src"], }, diff --git a/tests/func-tests/imx/package.json b/tests/func-tests/imx/package.json index 1a0cacd786..c7f68c0687 100644 --- a/tests/func-tests/imx/package.json +++ b/tests/func-tests/imx/package.json @@ -10,7 +10,6 @@ "devDependencies": { "@swc/jest": "^0.2.29", "@types/node": "^20.10.1", - "husky": "^8.0.0", "jest": "^29.7.0", "jest-cucumber": "^3.0.1", "pinst": "^3.0.0", @@ -18,14 +17,12 @@ "ts-node": "^10.9.1", "typescript": "^5.5.4" }, - "packageManager": "yarn@3.6.1", "resolutions": { "@openzeppelin/contracts": "3.4.2-solc-0.7" }, "scripts": { "func-test": "jest", "func-test:ci": "TAGS=\"not @skip and not @slow\" jest", - "postinstall": "cd ../../.. && husky install", "postpack": "pinst --enable", "prepack": "pinst --disable" } diff --git a/tests/func-tests/zkevm/package.json b/tests/func-tests/zkevm/package.json index 74271bf5aa..ac114a9c2d 100644 --- a/tests/func-tests/zkevm/package.json +++ b/tests/func-tests/zkevm/package.json @@ -22,7 +22,6 @@ "devDependencies": { "@swc/jest": "^0.2.29", "@types/node": "^20.10.1", - "husky": "^8.0.0", "jest": "^29.7.0", "jest-cucumber": "^3.0.1", "pinst": "^3.0.0", @@ -30,12 +29,10 @@ "ts-node": "^10.9.2", "typescript": "^5.5.4" }, - "packageManager": "yarn@3.6.1", "scripts": { "compile": "npx hardhat compile", "func-test": "yarn compile && jest", "func-test:ci": "yarn compile && TAGS=\"not @skip and not @slow\" jest", - "postinstall": "cd ../../.. && husky install", "postpack": "pinst --enable", "prepack": "pinst --disable" } diff --git a/tests/func-tests/zkevm/step-definitions/order.steps.ts b/tests/func-tests/zkevm/step-definitions/order.steps.ts index 95ba967efc..90214d47c5 100644 --- a/tests/func-tests/zkevm/step-definitions/order.steps.ts +++ b/tests/func-tests/zkevm/step-definitions/order.steps.ts @@ -1,7 +1,7 @@ import { Wallet } from 'ethers'; import { defineFeature, loadFeature } from 'jest-cucumber'; import { orderbook } from '@imtbl/sdk'; -import { Environment } from '@imtbl/config'; +import { Environment } from '@imtbl/sdk/config' import { getConfigFromEnv, getRandomTokenId, diff --git a/tsconfig.base.json b/tsconfig.base.json index f6bd61966a..3ebd0139bf 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "es2022", "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "noEmit": true, "allowJs": false, "removeComments": false, @@ -12,13 +12,15 @@ "esModuleInterop": true, "declaration": true, "resolveJsonModule": true, - "skipLibCheck": false, + "skipLibCheck": true, "isolatedModules": true, - "incremental": true + "noEmitOnError": true }, "ts-node": { "compilerOptions": { - "module": "commonjs" + "module": "commonjs", + "moduleResolution": "node", + "customConditions": null } } } diff --git a/yarn.lock b/yarn.lock index b4eec49355..921d7cebcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4198,6 +4198,7 @@ __metadata: ts-mockito: ^2.6.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4226,6 +4227,7 @@ __metadata: ts-node: ^10.9.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4237,6 +4239,8 @@ __metadata: "@imtbl/checkout-sdk": 0.0.0 "@imtbl/checkout-widgets": 0.0.0 "@imtbl/config": 0.0.0 + "@imtbl/orderbook": 0.0.0 + "@imtbl/passport": 0.0.0 "@svgr/webpack": ^8.0.1 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^13.4.0 @@ -4276,6 +4280,7 @@ __metadata: "@imtbl/bridge-sdk": 0.0.0 "@imtbl/config": 0.0.0 "@imtbl/dex-sdk": 0.0.0 + "@imtbl/generated-clients": 0.0.0 "@imtbl/metrics": 0.0.0 "@imtbl/orderbook": 0.0.0 "@imtbl/passport": 0.0.0 @@ -4288,6 +4293,7 @@ __metadata: "@rollup/plugin-replace": ^5.0.7 "@rollup/plugin-terser": ^0.4.4 "@rollup/plugin-typescript": ^11.1.6 + "@swc/core": ^1.3.36 "@types/uuid": ^8.3.4 axios: ^1.6.5 babel-jest: ^29.5.0 @@ -4302,6 +4308,7 @@ __metadata: typedoc: ^0.26.5 typedoc-plugin-markdown: ^4.2.3 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 uuid: ^8.3.2 languageName: unknown linkType: soft @@ -4316,6 +4323,7 @@ __metadata: "@imtbl/checkout-widgets": 0.0.0 "@imtbl/config": 0.0.0 "@imtbl/passport": 0.0.0 + "@swc/core": ^1.3.36 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^13.4.0 "@testing-library/user-event": ^13.5.0 @@ -4331,6 +4339,7 @@ __metadata: react-dom: ^18.2.0 react-router-dom: ^6.11.0 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 vite: ^5.0.12 vite-plugin-node-polyfills: ^0.16.0 web-vitals: ^2.1.4 @@ -4359,6 +4368,7 @@ __metadata: "@rollup/plugin-terser": ^0.4.4 "@rollup/plugin-typescript": ^11.1.6 "@svgr/webpack": ^8.0.1 + "@swc/core": ^1.3.36 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^13.4.0 "@testing-library/user-event": ^13.5.0 @@ -4386,12 +4396,14 @@ __metadata: react-i18next: ^13.5.0 react-scripts: 5.0.1 rollup: ^4.19.1 + rollup-plugin-polyfill-node: ^0.13.0 rollup-plugin-svg: ^2.0.0 rollup-plugin-visualizer: ^5.12.0 stream-browserify: ^3.0.0 stream-http: ^3.2.0 ts-jest: ^29.1.0 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 url: ^0.11.0 web-vitals: ^2.1.4 languageName: unknown @@ -4416,6 +4428,7 @@ __metadata: rollup: ^4.19.1 ts-node: ^10.9.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4460,6 +4473,7 @@ __metadata: rollup: ^4.19.1 ts-node: ^10.9.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4469,6 +4483,7 @@ __metadata: dependencies: "@imtbl/config": 0.0.0 "@rollup/plugin-json": ^6.1.0 + "@rollup/plugin-typescript": ^11.1.6 "@swc/core": ^1.3.36 "@swc/jest": ^0.2.24 "@typechain/ethers-v5": ^10.2.0 @@ -4485,6 +4500,7 @@ __metadata: ts-node: ^10.9.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4510,6 +4526,7 @@ __metadata: ts-node: ^10.9.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4533,9 +4550,12 @@ __metadata: resolution: "@imtbl/generated-clients@workspace:packages/internal/generated-clients" dependencies: "@openapitools/openapi-generator-cli": ^2.13.4 + "@rollup/plugin-typescript": ^11.1.6 + "@swc/core": ^1.3.36 jest: ^29.4.3 rollup: ^4.19.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4544,6 +4564,8 @@ __metadata: resolution: "@imtbl/guardian@workspace:packages/internal/guardian" dependencies: "@rollup/plugin-json": ^6.1.0 + "@rollup/plugin-node-resolve": ^15.2.3 + "@rollup/plugin-typescript": ^11.1.6 "@swc/core": ^1.3.36 "@swc/jest": ^0.2.24 "@typechain/ethers-v5": ^10.2.0 @@ -4557,6 +4579,7 @@ __metadata: ts-node: ^10.9.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4565,6 +4588,7 @@ __metadata: resolution: "@imtbl/metrics@workspace:packages/internal/metrics" dependencies: "@rollup/plugin-typescript": ^11.1.6 + "@swc/core": ^1.3.36 "@swc/jest": ^0.2.24 "@types/jest": ^29.4.3 axios: ^1.6.5 @@ -4576,6 +4600,7 @@ __metadata: rollup: ^4.19.1 ts-jest: ^29.1.0 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4585,6 +4610,7 @@ __metadata: dependencies: "@imtbl/blockchain-data": 0.0.0 "@imtbl/config": 0.0.0 + "@imtbl/generated-clients": 0.0.0 "@imtbl/metrics": 0.0.0 "@imtbl/webhook": 0.0.0 "@rollup/plugin-typescript": ^11.1.6 @@ -4603,6 +4629,7 @@ __metadata: testcontainers: ^10.9.0 ts-mockito: ^2.6.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 dependenciesMeta: pg: optional: true @@ -4619,6 +4646,7 @@ __metadata: "@imtbl/metrics": 0.0.0 "@opensea/seaport-js": 4.0.3 "@rollup/plugin-typescript": ^11.1.6 + "@swc/core": ^1.3.36 "@swc/jest": ^0.2.24 "@typechain/ethers-v5": ^10.2.0 "@types/jest": ^29.4.3 @@ -4635,6 +4663,7 @@ __metadata: ts-mockito: ^2.6.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4646,12 +4675,14 @@ __metadata: "@biom3/react": ^0.25.0 "@imtbl/blockchain-data": 0.0.0 "@imtbl/config": 0.0.0 + "@imtbl/generated-clients": 0.0.0 "@imtbl/orderbook": 0.0.0 "@imtbl/passport": 0.0.0 "@imtbl/x-client": 0.0.0 "@imtbl/x-provider": 0.0.0 "@metamask/detect-provider": ^2.0.0 "@next/eslint-plugin-next": ^13.4.7 + "@swc/core": ^1.3.36 "@types/node": ^18.14.2 "@types/react": ^18.0.28 "@types/react-dom": ^18.0.11 @@ -4665,7 +4696,7 @@ __metadata: eslint-config-next: 13.3.1 ethers: ^5.7.2 framer-motion: ^11.0.6 - next: 13.3.1 + next: 13.4.11 react: ^18.2.0 react-bootstrap: ^2.7.2 react-dom: ^18.2.0 @@ -4717,6 +4748,7 @@ __metadata: rollup: ^4.19.1 ts-node: ^10.9.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 uuid: ^8.3.2 languageName: unknown linkType: soft @@ -4928,6 +4960,7 @@ __metadata: rollup: ^4.19.1 ts-node: ^10.9.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4952,6 +4985,7 @@ __metadata: ts-mockito: ^2.6.1 typechain: ^8.1.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -4968,6 +5002,7 @@ __metadata: "@imtbl/config": 0.0.0 "@imtbl/generated-clients": 0.0.0 "@rollup/plugin-typescript": ^11.1.6 + "@swc/core": ^1.3.36 "@swc/jest": ^0.2.24 "@types/jest": ^29.4.3 axios: ^1.6.5 @@ -4981,6 +5016,7 @@ __metadata: jest-environment-jsdom: ^29.4.3 rollup: ^4.19.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -5015,6 +5051,7 @@ __metadata: rollup: ^4.19.1 ts-node: ^10.9.1 typescript: ^5.5.4 + unplugin-swc: ^1.5.1 languageName: unknown linkType: soft @@ -6835,10 +6872,10 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:13.3.1": - version: 13.3.1 - resolution: "@next/env@npm:13.3.1" - checksum: 3bf01e62b7de1de9de0cf7a5904364a2e807ad4f0a6cabfbb288225696a0750163bee23669bd45bfbec17dcf1fe66512212bdfa5be0a341ad187270a3cc27943 +"@next/env@npm:13.4.11": + version: 13.4.11 + resolution: "@next/env@npm:13.4.11" + checksum: f0181ae16ba3f7bbf6e7ce9b431218740b800ab3c2a61a50a75828794eecb7e6fe324f0547bfc6d80221ab3f4b812184a040c7c72b0f37c2f0c3742047f352c6 languageName: node linkType: hard @@ -6892,9 +6929,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-darwin-arm64@npm:13.3.1" +"@next/swc-darwin-arm64@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-darwin-arm64@npm:13.4.11" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -6913,9 +6950,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-darwin-x64@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-darwin-x64@npm:13.3.1" +"@next/swc-darwin-x64@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-darwin-x64@npm:13.4.11" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -6934,9 +6971,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-linux-arm64-gnu@npm:13.3.1" +"@next/swc-linux-arm64-gnu@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-linux-arm64-gnu@npm:13.4.11" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -6955,9 +6992,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-linux-arm64-musl@npm:13.3.1" +"@next/swc-linux-arm64-musl@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-linux-arm64-musl@npm:13.4.11" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -6976,9 +7013,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-linux-x64-gnu@npm:13.3.1" +"@next/swc-linux-x64-gnu@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-linux-x64-gnu@npm:13.4.11" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -6997,9 +7034,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-linux-x64-musl@npm:13.3.1" +"@next/swc-linux-x64-musl@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-linux-x64-musl@npm:13.4.11" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -7018,9 +7055,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-win32-arm64-msvc@npm:13.3.1" +"@next/swc-win32-arm64-msvc@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-win32-arm64-msvc@npm:13.4.11" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -7039,9 +7076,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-win32-ia32-msvc@npm:13.3.1" +"@next/swc-win32-ia32-msvc@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-win32-ia32-msvc@npm:13.4.11" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -7060,9 +7097,9 @@ __metadata: languageName: node linkType: hard -"@next/swc-win32-x64-msvc@npm:13.3.1": - version: 13.3.1 - resolution: "@next/swc-win32-x64-msvc@npm:13.3.1" +"@next/swc-win32-x64-msvc@npm:13.4.11": + version: 13.4.11 + resolution: "@next/swc-win32-x64-msvc@npm:13.4.11" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -11781,12 +11818,12 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:0.5.0": - version: 0.5.0 - resolution: "@swc/helpers@npm:0.5.0" +"@swc/helpers@npm:0.5.1, @swc/helpers@npm:^0.5.0": + version: 0.5.1 + resolution: "@swc/helpers@npm:0.5.1" dependencies: tslib: ^2.4.0 - checksum: 61c9c7dddb707deb58b85328cfe9d211887145f1311ae6a6e6c0fa9f781fb29916a8669a7d479e46e26a32a89d6ef4f293a22dee4925e009c84051e9dd10e8b7 + checksum: 71e0e27234590435e4c62b97ef5e796f88e786841a38c7116a5e27a3eafa7b9ead7cdec5249b32165902076de78446945311c973e59bddf77c1e24f33a8f272a languageName: node linkType: hard @@ -11800,15 +11837,6 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:^0.5.0": - version: 0.5.1 - resolution: "@swc/helpers@npm:0.5.1" - dependencies: - tslib: ^2.4.0 - checksum: 71e0e27234590435e4c62b97ef5e796f88e786841a38c7116a5e27a3eafa7b9ead7cdec5249b32165902076de78446945311c973e59bddf77c1e24f33a8f272a - languageName: node - linkType: hard - "@swc/jest@npm:^0.2.24": version: 0.2.27 resolution: "@swc/jest@npm:0.2.27" @@ -11948,7 +11976,6 @@ __metadata: "@swc/jest": ^0.2.29 "@types/node": ^20.10.1 dotenv: ^16.3.1 - husky: ^8.0.0 jest: ^29.7.0 jest-cucumber: ^3.0.1 pinst: ^3.0.0 @@ -11980,7 +12007,6 @@ __metadata: ethers: ^5.7.0 hardhat: ^2.19.4 hardhat-gas-reporter: ^1.0.8 - husky: ^8.0.0 jest: ^29.7.0 jest-cucumber: ^3.0.1 pinst: ^3.0.0 @@ -15086,6 +15112,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.12.1": + version: 8.12.1 + resolution: "acorn@npm:8.12.1" + bin: + acorn: bin/acorn + checksum: 677880034aee5bdf7434cc2d25b641d7bedb0b5ef47868a78dadabedccf58e1c5457526d9d8249cd253f2df087e081c3fe7d903b448d8e19e5131a3065b83c07 + languageName: node + linkType: hard + "address@npm:^1.0.1, address@npm:^1.1.2": version: 1.2.2 resolution: "address@npm:1.2.2" @@ -17631,7 +17666,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.4.0": +"chokidar@npm:^3.4.0, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -19822,7 +19857,7 @@ __metadata: concurrently: ^8.2.2 eslint: ^8.40.0 ethers: ^5.7.2 - next: 13.3.1 + next: 13.4.11 postcss: 8.4.31 react: ^18.2.0 react-dom: ^18.2.0 @@ -24943,7 +24978,7 @@ __metadata: languageName: node linkType: hard -"husky@npm:^8.0.0, husky@npm:^8.0.3": +"husky@npm:^8.0.3": version: 8.0.3 resolution: "husky@npm:8.0.3" bin: @@ -29098,6 +29133,13 @@ __metadata: languageName: node linkType: hard +"load-tsconfig@npm:^0.2.5": + version: 0.2.5 + resolution: "load-tsconfig@npm:0.2.5" + checksum: 631740833c4a7157bb7b6eeae6e1afb6a6fac7416b7ba91bd0944d5c5198270af2d68bf8347af3cc2ba821adc4d83ef98f66278bd263bc284c863a09ec441503 + languageName: node + linkType: hard + "loader-runner@npm:^4.2.0": version: 4.3.0 resolution: "loader-runner@npm:4.3.0" @@ -30494,29 +30536,30 @@ __metadata: languageName: node linkType: hard -"next@npm:13.3.1": - version: 13.3.1 - resolution: "next@npm:13.3.1" - dependencies: - "@next/env": 13.3.1 - "@next/swc-darwin-arm64": 13.3.1 - "@next/swc-darwin-x64": 13.3.1 - "@next/swc-linux-arm64-gnu": 13.3.1 - "@next/swc-linux-arm64-musl": 13.3.1 - "@next/swc-linux-x64-gnu": 13.3.1 - "@next/swc-linux-x64-musl": 13.3.1 - "@next/swc-win32-arm64-msvc": 13.3.1 - "@next/swc-win32-ia32-msvc": 13.3.1 - "@next/swc-win32-x64-msvc": 13.3.1 - "@swc/helpers": 0.5.0 +"next@npm:13.4.11": + version: 13.4.11 + resolution: "next@npm:13.4.11" + dependencies: + "@next/env": 13.4.11 + "@next/swc-darwin-arm64": 13.4.11 + "@next/swc-darwin-x64": 13.4.11 + "@next/swc-linux-arm64-gnu": 13.4.11 + "@next/swc-linux-arm64-musl": 13.4.11 + "@next/swc-linux-x64-gnu": 13.4.11 + "@next/swc-linux-x64-musl": 13.4.11 + "@next/swc-win32-arm64-msvc": 13.4.11 + "@next/swc-win32-ia32-msvc": 13.4.11 + "@next/swc-win32-x64-msvc": 13.4.11 + "@swc/helpers": 0.5.1 busboy: 1.6.0 caniuse-lite: ^1.0.30001406 postcss: 8.4.14 styled-jsx: 5.1.1 + watchpack: 2.4.0 + zod: 3.21.4 peerDependencies: "@opentelemetry/api": ^1.1.0 fibers: ">= 3.1.0" - node-sass: ^6.0.0 || ^7.0.0 react: ^18.2.0 react-dom: ^18.2.0 sass: ^1.3.0 @@ -30544,13 +30587,11 @@ __metadata: optional: true fibers: optional: true - node-sass: - optional: true sass: optional: true bin: next: dist/bin/next - checksum: a685abbcfe028940f8e3c86f6712fadcba1ca92c68b4dddfd1192d93a4ebac2d0947cd62d8cecf530afbd8163b2ef6dfe338b1fe7b699d78bc7123624a7622db + checksum: 3d6a7443bc1f22bc98db1cb87096df1e97c511a7cb8b0ee24469ea20bcfe50ba0b2baeb7e7ad9dba4c92cc126fc6809ba7f1690510ee2f54226bfd3173b921bd languageName: node linkType: hard @@ -35991,7 +36032,7 @@ __metadata: resolution: "seaport-core@https://github.com/immutable/seaport-core.git#commit=0633350ec34f21fcede657ff812f11cf7d19144e" dependencies: seaport-types: ^0.0.1 - checksum: d8adba0d54106c6fe9370f0775fadef2198e5eab440b36919d1f917705ce2f0a7028e4da021b6df049aa3ca35d7e673a28b78a731130f0ff9fdf7a8bd32e3b94 + checksum: 392bce86bbfc4f7c00b65575b238825f4c696bddf5af08be7aa496862e63879375387fd4400f6e900ffee08d65c1f75cf3adad9c6c41ddcf7a3b0389cd73c3c7 languageName: node linkType: hard @@ -36035,7 +36076,7 @@ __metadata: seaport-sol: ^1.5.0 seaport-types: ^0.0.1 solady: ^0.0.84 - checksum: a77e141e4ab5d2c4bb190a38fbb6cda3011fdf5f350b250fbeb4d82ae81cf917a966a2dcb8d9e4fd1bed29e5510ede9b15941b0ac77aeb4272dab94c9f51e7ff + checksum: f31a7443a50fa1c35ec03ea031743d1d10896653ae443fa15ab8e6f5b4a2ca43f6743d523ae4e1f14df867451e5b2b2130b0bfa58a1085b0bcae3fceb8dfdc9b languageName: node linkType: hard @@ -39651,6 +39692,31 @@ __metadata: languageName: node linkType: hard +"unplugin-swc@npm:^1.5.1": + version: 1.5.1 + resolution: "unplugin-swc@npm:1.5.1" + dependencies: + "@rollup/pluginutils": ^5.1.0 + load-tsconfig: ^0.2.5 + unplugin: ^1.11.0 + peerDependencies: + "@swc/core": ^1.2.108 + checksum: f278ccb085510f4cec3943a0f896465c67caee012bcea31beb630a8455adf190682745ee44cd791a922999d43c9f36fe5cbbe2e6e8f81dfbbae4d0ee07fc0642 + languageName: node + linkType: hard + +"unplugin@npm:^1.11.0": + version: 1.12.2 + resolution: "unplugin@npm:1.12.2" + dependencies: + acorn: ^8.12.1 + chokidar: ^3.6.0 + webpack-sources: ^3.2.3 + webpack-virtual-modules: ^0.6.2 + checksum: 69daad6c52fe8ce871070d56880cadad7770fa24419ff169eb38b0b481f5578abb27b9963f3ed3b6794a217f0761b5371c2dd3708cdd40417f96ef36f7e259d5 + languageName: node + linkType: hard + "unquote@npm:~1.1.1": version: 1.1.1 resolution: "unquote@npm:1.1.1" @@ -40329,7 +40395,7 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^2.4.0": +"watchpack@npm:2.4.0, watchpack@npm:^2.4.0": version: 2.4.0 resolution: "watchpack@npm:2.4.0" dependencies: @@ -40710,6 +40776,13 @@ __metadata: languageName: node linkType: hard +"webpack-virtual-modules@npm:^0.6.2": + version: 0.6.2 + resolution: "webpack-virtual-modules@npm:0.6.2" + checksum: 7e8e1d63f35864c815420cc2f27da8561a1e028255040698a352717de0ba46d3b3faf16f06c1a1965217054c4c2894eb9af53a85451870e919b5707ce9c5822d + languageName: node + linkType: hard + "webpack@npm:^5.64.4": version: 5.88.2 resolution: "webpack@npm:5.88.2" From b4fe508b075f50573381d50a5601cad1e225f371 Mon Sep 17 00:00:00 2001 From: zaidarain1 Date: Mon, 19 Aug 2024 14:06:06 +1000 Subject: [PATCH 14/29] fix: [DX-3131] Fix slow dev rebuild for initial changed package (#2099) --- build-dependents.js | 2 +- dev.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build-dependents.js b/build-dependents.js index fb53b404a1..d0cf7cade7 100755 --- a/build-dependents.js +++ b/build-dependents.js @@ -23,7 +23,7 @@ try { if (isDependent || changedProject === currentProject) { // Rebuild the current project - const command = `nx run-many --target=d --projects=${currentProject} --parallel=5`; + const command = `nx run-many --target=d --projects=${currentProject} --parallel=5 --no-cloud`; console.log(`Running command: ${command}`); execSync(command, { stdio: 'inherit' }); diff --git a/dev.sh b/dev.sh index 44ad4a48d0..19f7726e37 100755 --- a/dev.sh +++ b/dev.sh @@ -28,5 +28,5 @@ fi # Run nx commands with the selected or provided package name echo "Running commands for package: $PACKAGE_NAME" -nx run $PACKAGE_NAME:d --parallel=5 +nx run $PACKAGE_NAME:d --parallel=5 --no-cloud nx watch --all -- node ./build-dependents.js \$NX_PROJECT_NAME $(echo $PACKAGE_NAME) \ No newline at end of file From 484cc5c7a54c65a82d20258aa382296f4af0db1c Mon Sep 17 00:00:00 2001 From: zaidarain1 Date: Tue, 20 Aug 2024 13:57:44 +1000 Subject: [PATCH 15/29] fix: [DX-3140] Fix react is not defined widgets sample app error (#2100) --- packages/checkout/widgets-lib/rollup.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/checkout/widgets-lib/rollup.config.js b/packages/checkout/widgets-lib/rollup.config.js index 059f2cc2a8..23a43cf842 100644 --- a/packages/checkout/widgets-lib/rollup.config.js +++ b/packages/checkout/widgets-lib/rollup.config.js @@ -17,7 +17,9 @@ const defaultPlugins = [ preventAssignment: true, 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || PRODUCTION), }), - isProduction ? typescript({customConditions: ["default"]}) : swc.rollup(), + isProduction ? typescript({customConditions: ["default"]}) : swc.rollup({ jsc: { + transform: { react: { development: true, runtime: 'automatic' }}, + } }), ] const productionPlugins = [ From 8c41ad0b94fcfde90a300cd86a7691f3ced5e485 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 04:02:13 +0000 Subject: [PATCH 16/29] chore(deps): bump elliptic from 6.5.4 to 6.5.7 (#2097) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/x-client/package.json | 2 +- sdk/package.json | 2 +- yarn.lock | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/x-client/package.json b/packages/x-client/package.json index e16c0d1314..b300e2efdd 100644 --- a/packages/x-client/package.json +++ b/packages/x-client/package.json @@ -15,7 +15,7 @@ "@imtbl/generated-clients": "0.0.0", "axios": "^1.6.5", "bn.js": "^5.2.1", - "elliptic": "^6.5.4", + "elliptic": "^6.5.7", "enc-utils": "^3.0.0", "ethereumjs-wallet": "^1.0.2", "ethers": "^5.7.2" diff --git a/sdk/package.json b/sdk/package.json index da6c49b339..97aac2c86f 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -33,7 +33,7 @@ "bn.js": "^5.2.1", "buffer": "^6.0.3", "crypto-browserify": "^3.12.0", - "elliptic": "^6.5.4", + "elliptic": "^6.5.7", "enc-utils": "^3.0.0", "ethereumjs-wallet": "^1.0.2", "ethers": "^5.7.2", diff --git a/yarn.lock b/yarn.lock index 921d7cebcb..5aca3f5539 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4819,7 +4819,7 @@ __metadata: bn.js: ^5.2.1 buffer: ^6.0.3 crypto-browserify: ^3.12.0 - elliptic: ^6.5.4 + elliptic: ^6.5.7 enc-utils: ^3.0.0 eslint: ^8.40.0 ethereumjs-wallet: ^1.0.2 @@ -5007,7 +5007,7 @@ __metadata: "@types/jest": ^29.4.3 axios: ^1.6.5 bn.js: ^5.2.1 - elliptic: ^6.5.4 + elliptic: ^6.5.7 enc-utils: ^3.0.0 eslint: ^8.40.0 ethereumjs-wallet: ^1.0.2 @@ -20408,6 +20408,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.5.7": + version: 6.5.7 + resolution: "elliptic@npm:6.5.7" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: af0ffddffdbc2fea4eeec74388cd73e62ed5a0eac6711568fb28071566319785df529c968b0bf1250ba4bc628e074b2d64c54a633e034aa6f0c6b152ceb49ab8 + languageName: node + linkType: hard + "embla-carousel-react@npm:^8.1.5": version: 8.1.5 resolution: "embla-carousel-react@npm:8.1.5" From c32a4c9db1a0fa3c2ee6e421cf1295b6c5e27d90 Mon Sep 17 00:00:00 2001 From: Alejandro Loaiza Date: Wed, 21 Aug 2024 11:11:24 +1000 Subject: [PATCH 17/29] feat: Adding swap method to checkout sdk (#2095) --- .../sdk-sample-app/src/components/Swap.tsx | 227 ++++++++++++++++++ .../src/pages/ConnectWidget.tsx | 12 + .../checkout/sdk/src/errors/checkoutError.ts | 1 + packages/checkout/sdk/src/sdk.test.ts | 132 ++++++++++ packages/checkout/sdk/src/sdk.ts | 25 ++ packages/checkout/sdk/src/swap/index.ts | 1 + packages/checkout/sdk/src/swap/swap.test.ts | 190 +++++++++++++++ packages/checkout/sdk/src/swap/swap.ts | 119 +++++++++ .../sdk/src/transaction/transaction.ts | 33 ++- packages/checkout/sdk/src/types/swap.ts | 50 ++++ 10 files changed, 785 insertions(+), 5 deletions(-) create mode 100644 packages/checkout/sdk-sample-app/src/components/Swap.tsx create mode 100644 packages/checkout/sdk/src/swap/index.ts create mode 100644 packages/checkout/sdk/src/swap/swap.test.ts create mode 100644 packages/checkout/sdk/src/swap/swap.ts create mode 100644 packages/checkout/sdk/src/types/swap.ts diff --git a/packages/checkout/sdk-sample-app/src/components/Swap.tsx b/packages/checkout/sdk-sample-app/src/components/Swap.tsx new file mode 100644 index 0000000000..20ac799146 --- /dev/null +++ b/packages/checkout/sdk-sample-app/src/components/Swap.tsx @@ -0,0 +1,227 @@ +import { ChainId, Checkout, GetBalanceResult, TokenInfo } from '@imtbl/checkout-sdk'; +import { Web3Provider } from '@ethersproject/providers'; +import LoadingButton from './LoadingButton'; +import { useEffect, useState } from 'react'; +import { SuccessMessage, ErrorMessage, WarningMessage } from './messages'; +import { Box, FormControl, TextInput } from '@biom3/react'; +import React from 'react'; + +interface SwapProps { + checkout: Checkout | undefined; + provider: Web3Provider | undefined; +} + +export default function Swap(props: SwapProps) { + const { provider, checkout } = props; + + const [fromToken, setFromToken] = useState(); + const [toToken, setToToken] = useState(); + const [fromAmount, setFromAmount] = useState(''); + const [toAmount, setToAmount] = useState(''); + const [slippagePercent, setSlippagePercent] = useState('0.1'); + const [maxHops, setMaxHops] = useState('2'); + const [deadline, setDeadline] = useState(() => { + const fifteenMinutesInSeconds = 15 * 60; + return Math.floor(Date.now() / 1000 + fifteenMinutesInSeconds).toString(); + }); + + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + const [success, setSuccess] = useState(false); + const [validationError, setValidationError] = useState(null); + + const [fromTokenDecimals, setFromTokenDecimals] = useState(18); + const [toTokenDecimals, setToTokenDecimals] = useState(18); + + const updateFromToken = (event: React.ChangeEvent) => { + setFromToken({ address: event.target.value, symbol: '', name: '', decimals: fromTokenDecimals }); + setError(null); + }; + + const updateToToken = (event: React.ChangeEvent) => { + setToToken({ address: event.target.value, symbol: '', name: '', decimals: toTokenDecimals }); + setError(null); + }; + + const updateFromTokenDecimals = (event: React.ChangeEvent) => { + const decimals = parseInt(event.target.value) || 18; + setFromTokenDecimals(decimals); + setFromToken(prevToken => prevToken ? { ...prevToken, decimals } : undefined); + setError(null); + }; + + const updateToTokenDecimals = (event: React.ChangeEvent) => { + const decimals = parseInt(event.target.value) || 18; + setToTokenDecimals(decimals); + setToToken(prevToken => prevToken ? { ...prevToken, decimals } : undefined); + setError(null); + }; + + const updateFromAmount = (event: React.ChangeEvent) => { + const newFromAmount = event.target.value; + setFromAmount(newFromAmount); + setError(null); + validateAmounts(newFromAmount, toAmount); + }; + + const updateToAmount = (event: React.ChangeEvent) => { + const newToAmount = event.target.value; + setToAmount(newToAmount); + setError(null); + validateAmounts(fromAmount, newToAmount); + }; + + const validateAmounts = (from: string, to: string) => { + if (from !== '' && to !== '') { + setValidationError('Please provide either From Amount or To Amount, not both.'); + } else { + setValidationError(null); + } + }; + + const updateSlippagePercent = (event: React.ChangeEvent) => { + setSlippagePercent(event.target.value); + setError(null); + }; + + const updateMaxHops = (event: React.ChangeEvent) => { + setMaxHops(event.target.value); + setError(null); + }; + + const updateDeadline = (event: React.ChangeEvent) => { + setDeadline(event.target.value); + setError(null); + }; + + async function performSwap() { + if (validationError) { + setError(new Error(validationError)); + return; + } + if (!checkout) { + console.error('missing checkout, please connect first'); + return; + } + if (!provider) { + console.error('missing provider, please connect first'); + return; + } + if (!fromToken || !toToken) { + console.error('missing token information'); + return; + } + setError(null); + setLoading(true); + setSuccess(false); + + try { + const result = await checkout.swap({ + provider, + fromToken, + toToken, + fromAmount, + toAmount, + slippagePercent: slippagePercent.trim() !== '' ? parseFloat(slippagePercent) : undefined, + maxHops: maxHops.trim() !== '' ? parseInt(maxHops) : undefined, + deadline: deadline.trim() !== '' ? parseInt(deadline) : undefined, + }); + console.log('Swap result:', result); + setSuccess(true); + setLoading(false); + } catch (err: any) { + setError(err); + setLoading(false); + console.log(err.message); + console.log(err.type); + console.log(err.data); + console.log(err.stack); + } + } + + useEffect(() => { + setError(null); + setLoading(false); + setSuccess(false); + }, [checkout]); + + return ( +
+ {!provider && Not connected.} + + + + + + + + + + + + + + + + + + +
From Token AddressDecimalsTo Token AddressDecimals
+ + + + + + + + + + + + + + + +
+ + From Amount + + + + To Amount + + + {validationError && {validationError}} + + Slippage Percent + + + + Max Hops + + + + Deadline (minutes) + + + + + Swap + + + {success && !error && ( + Swap successful. Check console for details. + )} + {error && ( + + {error.message}. Check console logs for more details. + + )} +
+
+ ); +} \ No newline at end of file diff --git a/packages/checkout/sdk-sample-app/src/pages/ConnectWidget.tsx b/packages/checkout/sdk-sample-app/src/pages/ConnectWidget.tsx index 046693dc12..2c207ac1fd 100644 --- a/packages/checkout/sdk-sample-app/src/pages/ConnectWidget.tsx +++ b/packages/checkout/sdk-sample-app/src/pages/ConnectWidget.tsx @@ -12,6 +12,7 @@ import { Environment } from '@imtbl/config'; import Provider from '../components/Provider'; import SendTransaction from '../components/SendTransaction'; import GetInjectedProviders from '../components/GetInjectedProviders'; +import Swap from '../components/Swap'; export default function ConnectWidget() { const [environment, setEnvironment] = useState(Environment.SANDBOX); @@ -168,6 +169,17 @@ export default function ConnectWidget() { Get injected providers + + + Swap + + +
); } diff --git a/packages/checkout/sdk/src/errors/checkoutError.ts b/packages/checkout/sdk/src/errors/checkoutError.ts index 7b2f7a1221..6e1246aa48 100644 --- a/packages/checkout/sdk/src/errors/checkoutError.ts +++ b/packages/checkout/sdk/src/errors/checkoutError.ts @@ -42,6 +42,7 @@ export enum CheckoutErrorType { API_ERROR = 'API_ERROR', ORDER_EXPIRED_ERROR = 'ORDER_EXPIRED_ERROR', WIDGETS_SCRIPT_LOAD_ERROR = 'WIDGETS_SCRIPT_LOAD_ERROR', + APPROVAL_TRANSACTION_FAILED = 'APPROVAL_TRANSACTION_FAILED', } /** diff --git a/packages/checkout/sdk/src/sdk.test.ts b/packages/checkout/sdk/src/sdk.test.ts index 9ab48fac68..911c40514e 100644 --- a/packages/checkout/sdk/src/sdk.test.ts +++ b/packages/checkout/sdk/src/sdk.test.ts @@ -55,6 +55,8 @@ import { FiatRampParams, ExchangeType } from './types/fiatRamp'; import { getItemRequirementsFromRequirements } from './smartCheckout/itemRequirements'; import { CheckoutErrorType } from './errors'; import { availabilityService } from './availability'; +import * as swap from './swap'; +import { SwapParams, SwapResult } from './types/swap'; jest.mock('./connect'); jest.mock('./network'); @@ -72,6 +74,7 @@ jest.mock('./smartCheckout'); jest.mock('./fiatRamp'); jest.mock('./smartCheckout/itemRequirements'); jest.mock('./availability'); +jest.mock('./swap'); describe('Connect', () => { let providerMock: ExternalProvider; @@ -989,4 +992,133 @@ describe('Connect', () => { expect(checkout.availability.checkDexAvailability).toBeCalledTimes(1); }); }); + + describe('Swap', () => { + let checkout: Checkout; + let web3Provider: Web3Provider; + + beforeEach(() => { + jest.resetAllMocks(); + + providerMock.request = jest.fn().mockResolvedValue('0x1'); + + web3Provider = new Web3Provider(providerMock, ChainId.ETHEREUM); + + (validateProvider as jest.Mock).mockResolvedValue(web3Provider); + + checkout = new Checkout({ + baseConfig: { environment: Environment.PRODUCTION }, + }); + }); + + it('should call swap function with correct parameters', async () => { + const swapParams: SwapParams = { + provider: web3Provider, + fromToken: { address: '0xFromTokenAddress', decimals: 18 } as TokenInfo, + toToken: { address: '0xToTokenAddress', decimals: 18 } as TokenInfo, + fromAmount: '1000000000000000000', // 1 ETH in wei + toAmount: '1000000', // Example USDC amount + slippagePercent: 0.5, + maxHops: 3, + deadline: 1234567890, + }; + + const mockSwapResult: SwapResult = { + swap: { + transaction: { + to: '0xSwapContractAddress', + data: '0xEncodedSwapData', + value: '0', + }, + gasFeeEstimate: { + token: { + chainId: 0, + address: '', + decimals: 0, + symbol: undefined, + name: undefined, + }, + value: BigNumber.from('1000000000000000000'), + }, + }, + quote: { + slippage: 0.1, + fees: [], + amount: { + token: { + chainId: 0, + address: '', + decimals: 0, + symbol: undefined, + name: undefined, + }, + value: BigNumber.from('1000000000000000000'), + }, + amountWithMaxSlippage: { + token: { + chainId: 0, + address: '', + decimals: 0, + symbol: undefined, + name: undefined, + }, + value: BigNumber.from('1050000000000000000'), // Example value with 5% max slippage + }, + }, + swapReceipt: { + to: '0xRecipientAddress', + from: '0xSenderAddress', + contractAddress: '0xContractAddress', + transactionIndex: 1, + gasUsed: BigNumber.from('21000'), + logsBloom: '0x', + blockHash: '0xBlockHash', + transactionHash: '0xTransactionHash', + logs: [], + blockNumber: 12345, + confirmations: 2, + cumulativeGasUsed: BigNumber.from('100000'), + effectiveGasPrice: BigNumber.from('20000000000'), + status: 1, + type: 2, + byzantium: true, + }, + }; + + (swap.swap as jest.Mock).mockResolvedValue(mockSwapResult); + + const result = await checkout.swap(swapParams); + + expect(validateProvider).toHaveBeenCalledWith(checkout.config, web3Provider); + expect(swap.swap).toHaveBeenCalledWith( + checkout.config, + web3Provider, + swapParams.fromToken, + swapParams.toToken, + swapParams.fromAmount, + swapParams.toAmount, + swapParams.slippagePercent, + swapParams.maxHops, + swapParams.deadline, + ); + expect(result).toEqual(mockSwapResult); + }); + + it('should throw an error if provider validation fails', async () => { + const error = new Error('Invalid provider'); + (validateProvider as jest.Mock).mockRejectedValue(error); + + const swapParams: SwapParams = { + provider: web3Provider, + fromToken: { address: '0xFromTokenAddress', decimals: 18 } as TokenInfo, + toToken: { address: '0xToTokenAddress', decimals: 18 } as TokenInfo, + fromAmount: '1000000000000000000', + toAmount: '1000000', + slippagePercent: 0.5, + }; + + await expect(checkout.swap(swapParams)).rejects.toThrow('Invalid provider'); + expect(swap.swap).not.toHaveBeenCalled(); + }); + }); }); diff --git a/packages/checkout/sdk/src/sdk.ts b/packages/checkout/sdk/src/sdk.ts index ed1a85c58f..131bed0081 100644 --- a/packages/checkout/sdk/src/sdk.ts +++ b/packages/checkout/sdk/src/sdk.ts @@ -17,6 +17,7 @@ import * as buy from './smartCheckout/buy'; import * as cancel from './smartCheckout/cancel'; import * as sell from './smartCheckout/sell'; import * as smartCheckout from './smartCheckout'; +import * as swap from './swap'; import { AddNetworkParams, BuyParams, @@ -76,6 +77,7 @@ import { WidgetConfiguration } from './widgets/definitions/configurations'; import { SemanticVersion } from './widgets/definitions/types'; import { validateAndBuildVersion } from './widgets/version'; import { InjectedProvidersManager } from './provider/injectedProvidersManager'; +import { SwapParams, SwapResult } from './types/swap'; const SANDBOX_CONFIGURATION = { baseConfig: { @@ -722,4 +724,27 @@ export class Checkout { public async isSwapAvailable(): Promise { return this.availability.checkDexAvailability(); } + + /** + * Fetches the approval and swap transaction details including the quote for the swap. + * @param {SwapParams} params - The parameters for the swap. + * @returns {Promise} - A promise that resolves to the swap result (swap tx, swap tx receipt, quote used in the swap). + */ + public async swap(params: SwapParams): Promise { + const web3Provider = await provider.validateProvider( + this.config, + params.provider, + ); + return swap.swap( + this.config, + web3Provider, + params.fromToken, + params.toToken, + params.fromAmount, + params.toAmount, + params.slippagePercent, + params.maxHops, + params.deadline, + ); + } } diff --git a/packages/checkout/sdk/src/swap/index.ts b/packages/checkout/sdk/src/swap/index.ts new file mode 100644 index 0000000000..b16905623b --- /dev/null +++ b/packages/checkout/sdk/src/swap/index.ts @@ -0,0 +1 @@ +export * from './swap'; diff --git a/packages/checkout/sdk/src/swap/swap.test.ts b/packages/checkout/sdk/src/swap/swap.test.ts new file mode 100644 index 0000000000..d233645f95 --- /dev/null +++ b/packages/checkout/sdk/src/swap/swap.test.ts @@ -0,0 +1,190 @@ +import { Web3Provider } from '@ethersproject/providers'; +import { BigNumber, utils, ethers } from 'ethers'; +import { CheckoutConfiguration } from '../config/config'; +import { TokenInfo } from '../types'; +import { swap, swapQuote } from './swap'; +import { createExchangeInstance } from '../instance'; + +jest.mock('../instance', () => ({ + createExchangeInstance: jest.fn(), +})); + +describe('swapQuote', () => { + const mockChainId = 13473; + const mockConfig = {} as unknown as CheckoutConfiguration; + const mockProvider = { + getSigner: jest.fn().mockReturnValue({ + getAddress: jest.fn().mockResolvedValue('0xmockaddress'), + }), + } as unknown as Web3Provider; + const mockFromToken: TokenInfo = { + address: '0x123', + symbol: 'FROM', + decimals: 18, + name: 'From Token', + }; + const mockToToken: TokenInfo = { + address: '0x456', + symbol: 'TO', + decimals: 18, + name: 'To Token', + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call createExchangeInstance and execute swapQuote with fromAmount', async () => { + const mockExchange = { + getUnsignedSwapTxFromAmountIn: jest.fn().mockResolvedValue({ quote: '0xquotehash' }), + }; + (createExchangeInstance as jest.Mock).mockResolvedValue(mockExchange); + + const result = await swapQuote(mockConfig, mockProvider, mockFromToken, mockToToken, '100'); + + expect(createExchangeInstance).toHaveBeenCalledWith(mockChainId, mockConfig); + expect(mockExchange.getUnsignedSwapTxFromAmountIn).toHaveBeenCalledWith( + '0xmockaddress', + mockFromToken.address, + mockToToken.address, + BigNumber.from(utils.parseUnits('100', mockFromToken.decimals)), + undefined, + undefined, + undefined, + ); + expect(result).toEqual({ quote: '0xquotehash' }); + }); + + it('should call createExchangeInstance and execute swapQuote with toAmount', async () => { + const mockExchange = { + getUnsignedSwapTxFromAmountOut: jest.fn().mockResolvedValue({ quote: '0xquotehash' }), + }; + (createExchangeInstance as jest.Mock).mockResolvedValue(mockExchange); + + const result = await swapQuote(mockConfig, mockProvider, mockFromToken, mockToToken, undefined, '200'); + + expect(createExchangeInstance).toHaveBeenCalledWith(mockChainId, mockConfig); + expect(mockExchange.getUnsignedSwapTxFromAmountOut).toHaveBeenCalledWith( + '0xmockaddress', + mockFromToken.address, + mockToToken.address, + BigNumber.from(utils.parseUnits('200', mockToToken.decimals)), + undefined, + undefined, + undefined, + ); + expect(result).toEqual({ quote: '0xquotehash' }); + }); + + it('should throw an error if fromToken address is missing', async () => { + const invalidFromToken = { ...mockFromToken, address: '' }; + await expect(swapQuote(mockConfig, mockProvider, invalidFromToken, mockToToken, '100')) + .rejects.toThrow('fromToken address or decimals is missing.'); + }); + + it('should throw an error if fromToken decimals is zero', async () => { + const invalidFromToken = { ...mockFromToken, decimals: 0 }; + await expect(swapQuote(mockConfig, mockProvider, invalidFromToken, mockToToken, '100')) + .rejects.toThrow('fromToken address or decimals is missing.'); + }); + + it('should throw an error if toToken address is missing', async () => { + const invalidToToken = { ...mockToToken, address: '' }; + await expect(swapQuote(mockConfig, mockProvider, mockFromToken, invalidToToken, '100')) + .rejects.toThrow('toToken address or decimals is missing.'); + }); + + it('should throw an error if toToken decimals is zero', async () => { + const invalidToToken = { ...mockToToken, decimals: 0 }; + await expect(swapQuote(mockConfig, mockProvider, mockFromToken, invalidToToken, '100')) + .rejects.toThrow('toToken address or decimals is missing.'); + }); + + it('should throw an error if both fromAmount and toAmount are provided', async () => { + await expect(swapQuote(mockConfig, mockProvider, mockFromToken, mockToToken, '100', '200')) + .rejects.toThrow('Only one of fromAmount or toAmount can be provided.'); + }); + + it('should throw an error if neither fromAmount nor toAmount is provided', async () => { + await expect(swapQuote(mockConfig, mockProvider, mockFromToken, mockToToken)) + .rejects.toThrow('fromAmount or toAmount must be provided.'); + }); +}); + +describe('swap', () => { + const mockChainId = 13473; + const mockConfig = {} as unknown as CheckoutConfiguration; + const mockSigner = { + getAddress: jest.fn().mockResolvedValue('0xmockaddress'), + sendTransaction: jest.fn().mockResolvedValue({ hash: '0xtxhash' }), + }; + const mockProvider = { + getSigner: jest.fn().mockReturnValue(mockSigner), + getNetwork: jest.fn().mockResolvedValue({ chainId: mockChainId }), + } as unknown as Web3Provider; + const mockFromToken: TokenInfo = { + address: '0x123', + symbol: 'FROM', + decimals: 18, + name: 'From Token', + }; + const mockToToken: TokenInfo = { + address: '0x456', + symbol: 'TO', + decimals: 18, + name: 'To Token', + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should successfully execute a swap', async () => { + const mockTransactionResponse = { + wait: jest.fn().mockResolvedValue({ status: 1 }), + }; + + const mockExchange = { + getUnsignedSwapTxFromAmountIn: jest.fn().mockResolvedValue({ + quote: '0xquotehash', + swap: { transaction: { maxFeePerGas: '0xunsignedtx' } as ethers.providers.TransactionRequest }, + approve: { transaction: { maxFeePerGas: '0xunsignedtx' } as ethers.providers.TransactionRequest }, + }), + }; + (createExchangeInstance as jest.Mock).mockResolvedValue(mockExchange); + + mockSigner.sendTransaction.mockResolvedValue({ + ...mockTransactionResponse, + hash: '0xtxhash', + }); + + const result = await swap(mockConfig, mockProvider, mockFromToken, mockToToken, '100'); + + expect(createExchangeInstance).toHaveBeenCalledWith(mockChainId, mockConfig); + expect(mockExchange.getUnsignedSwapTxFromAmountIn).toHaveBeenCalledWith( + '0xmockaddress', + mockFromToken.address, + mockToToken.address, + BigNumber.from(utils.parseUnits('100', mockFromToken.decimals)), + undefined, + undefined, + undefined, + ); + expect(mockProvider.getNetwork).toHaveBeenCalled(); + expect(mockSigner.sendTransaction).toHaveBeenCalledWith({ + maxFeePerGas: BigNumber.from('0x037e11d600'), + maxPriorityFeePerGas: BigNumber.from('0x02540be400'), + }); + expect(mockTransactionResponse.wait).toHaveBeenCalled(); + expect(result).toEqual({ + quote: '0xquotehash', + swap: { + transaction: { + maxFeePerGas: BigNumber.from('0x037e11d600'), + maxPriorityFeePerGas: BigNumber.from('0x02540be400'), + }, + }, + swapReceipt: { status: 1 }, + }); + }); +}); diff --git a/packages/checkout/sdk/src/swap/swap.ts b/packages/checkout/sdk/src/swap/swap.ts new file mode 100644 index 0000000000..990b65e43b --- /dev/null +++ b/packages/checkout/sdk/src/swap/swap.ts @@ -0,0 +1,119 @@ +import { BigNumber, utils } from 'ethers'; +import { Web3Provider } from '@ethersproject/providers'; +import { CheckoutError, CheckoutErrorType } from '../errors'; +import { TokenInfo } from '../types'; +import { createExchangeInstance } from '../instance'; +import { CheckoutConfiguration, getL2ChainId } from '../config'; +import { SwapQuoteResult, SwapResult } from '../types/swap'; +import { sendTransaction } from '../transaction/transaction'; + +const swapQuote = async ( + config: CheckoutConfiguration, + provider: Web3Provider, + fromToken: TokenInfo, + toToken: TokenInfo, + fromAmount?: string, + toAmount?: string, + slippagePercent?: number, + maxHops?: number, + deadline?: number, +): Promise => { + if (!fromToken.address || fromToken.decimals === 0) { + throw new CheckoutError( + 'fromToken address or decimals is missing.', + CheckoutErrorType.MISSING_PARAMS, + ); + } + if (!toToken.address || toToken.decimals === 0) { + throw new CheckoutError( + 'toToken address or decimals is missing.', + CheckoutErrorType.MISSING_PARAMS, + ); + } + if (fromAmount && toAmount) { + throw new CheckoutError( + 'Only one of fromAmount or toAmount can be provided.', + CheckoutErrorType.MISSING_PARAMS, + ); + } + if (!fromAmount && !toAmount) { + throw new CheckoutError( + 'fromAmount or toAmount must be provided.', + CheckoutErrorType.MISSING_PARAMS, + ); + } + const chainId = getL2ChainId(config); + const exchange = await createExchangeInstance(chainId, config); + + const address = await provider.getSigner().getAddress(); + + if (fromAmount) { + return exchange.getUnsignedSwapTxFromAmountIn( + address, + fromToken.address as string, + toToken.address as string, + BigNumber.from(utils.parseUnits(fromAmount, fromToken.decimals)), + slippagePercent, + maxHops, + deadline, + ); + } + return exchange.getUnsignedSwapTxFromAmountOut( + address, + fromToken.address as string, + toToken.address as string, + BigNumber.from(utils.parseUnits(toAmount!, toToken.decimals)), + slippagePercent, + maxHops, + deadline, + ); +}; + +const swap = async ( + config: CheckoutConfiguration, + provider: Web3Provider, + fromToken: TokenInfo, + toToken: TokenInfo, + fromAmount?: string, + toAmount?: string, + slippagePercent?: number, + maxHops?: number, + deadline?: number, +): Promise => { + const quoteResult = await swapQuote( + config, + provider, + fromToken, + toToken, + fromAmount, + toAmount, + slippagePercent, + maxHops, + deadline, + ); + if (quoteResult.approval) { + const approvalTx = await sendTransaction(provider, quoteResult.approval.transaction); + const receipt = await approvalTx.transactionResponse.wait(); + if (receipt.status === 0) { + throw new CheckoutError( + 'Approval transaction failed and was reverted', + CheckoutErrorType.APPROVAL_TRANSACTION_FAILED, + ); + } + } + const swapTx = await sendTransaction(provider, quoteResult.swap.transaction); + const receipt = await swapTx.transactionResponse.wait(); + if (receipt.status === 0) { + throw new CheckoutError( + 'Swap transaction failed and was reverted', + CheckoutErrorType.TRANSACTION_FAILED, + ); + } + return { + swapReceipt: receipt, + quote: quoteResult.quote, + swap: quoteResult.swap, + }; +}; + +export { swapQuote, swap }; diff --git a/packages/checkout/sdk/src/transaction/transaction.ts b/packages/checkout/sdk/src/transaction/transaction.ts index 0834de62d4..c9a3c3983b 100644 --- a/packages/checkout/sdk/src/transaction/transaction.ts +++ b/packages/checkout/sdk/src/transaction/transaction.ts @@ -1,10 +1,31 @@ -import { ethers } from 'ethers'; +import { BigNumber, ethers } from 'ethers'; import { TransactionRequest, Web3Provider } from '@ethersproject/providers'; import { CheckoutError, CheckoutErrorType } from '../errors'; import { SendTransactionResult } from '../types'; import { IMMUTABLE_ZKVEM_GAS_OVERRIDES } from '../env'; import { isZkEvmChainId } from '../utils/utils'; +export function isPassportProvider(provider?: Web3Provider | null) { + return (provider?.provider as any)?.isPassport === true; +} + +/** + * Checks conditions to operate a gas-free flow. + * + * TODO: + * - Phase 1 (2024): Allow all passport wallets to be gas-free. + * - Phase 2 & 3 (2025): Not all passport wallets will be gas-free. + * Therefore, the gas-free condition must be checked against the relayer's + * `im_getFeeOptions` endpoint, which should return zero for + * passport accounts with gas sponsorship enabled. + * + * Refer to the docs for more details: + * https://docs.immutable.com/docs/zkevm/architecture/gas-sponsorship-for-gamers/ + */ +export function isGasFree(provider?: Web3Provider | null) { + return isPassportProvider(provider); +} + export const setTransactionGasLimits = async ( web3Provider: Web3Provider, transaction: TransactionRequest, @@ -14,10 +35,12 @@ export const setTransactionGasLimits = async ( const { chainId } = await web3Provider.getNetwork(); if (!isZkEvmChainId(chainId)) return rawTx; if (typeof rawTx.gasPrice !== 'undefined') return rawTx; - - rawTx.maxFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxFeePerGas; - rawTx.maxPriorityFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxPriorityFeePerGas; - + if (isGasFree(web3Provider)) { + rawTx.gasPrice = BigNumber.from(0); + } else { + rawTx.maxFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxFeePerGas; + rawTx.maxPriorityFeePerGas = IMMUTABLE_ZKVEM_GAS_OVERRIDES.maxPriorityFeePerGas; + } return rawTx; }; diff --git a/packages/checkout/sdk/src/types/swap.ts b/packages/checkout/sdk/src/types/swap.ts new file mode 100644 index 0000000000..5f0aab353d --- /dev/null +++ b/packages/checkout/sdk/src/types/swap.ts @@ -0,0 +1,50 @@ +import { TransactionReceipt, Web3Provider } from '@ethersproject/providers'; +import { Quote, TransactionDetails } from '@imtbl/dex-sdk'; +import { TokenInfo } from './tokenInfo'; + +/** + * Interface representing the parameters for {@link Checkout.swap}. + * @property {Web3Provider} provider - The provider used to get the wallet address. + * @property {TokenInfo} fromToken - The token to swap from. + * @property {TokenInfo} toToken - The token to swap to. + * @property {string | undefined} fromAmount - The amount to swap from. + * @property {string | undefined} toAmount - The amount to swap to. + * @property {number | undefined} slippagePercent - The percentage of slippage tolerance. Default = 0.1. Max = 50. Min = 0 + * @property {number | undefined} maxHops - Maximum hops allowed in optimal route. Default is 2 + * @property {number | undefined} deadline - Latest time swap can execute. Default is 15 minutes + */ + +export interface SwapParams { + provider: Web3Provider; + fromToken: TokenInfo, + toToken: TokenInfo, + fromAmount?: string, + toAmount?: string, + slippagePercent?: number, + maxHops?: number, + deadline?: number, +} + +/** + * Interface representing the result of {@link Checkout.swapQuote}. + * @property {TransactionDetails} approval - The approval transaction details. + * @property {TransactionDetails} swap - The swap transaction details. + * @property {Quote} quote - The quote for the swap. + */ +export interface SwapQuoteResult { + approval: TransactionDetails | null; + swap: TransactionDetails; + quote: Quote; +} + +/** + * Interface representing the result of {@link Checkout.swap}. + * @property {TransactionDetails} swap - The swap transaction details. + * @property {Quote} quote - The quote for the swap. + * @property {TransactionReceipt} swapReceipt - The receipt of the swap transaction. + */ +export interface SwapResult { + swap: TransactionDetails; + quote: Quote; + swapReceipt: TransactionReceipt; +} From a60950c2b025af3416a56acd099f584ee017d3c0 Mon Sep 17 00:00:00 2001 From: Jhonatan Gonzalez Date: Wed, 21 Aug 2024 09:41:47 +0800 Subject: [PATCH 18/29] [NO-CHANGELOG][Checkout Widgets] fix: Prevent passing provider as prop to framer motion children (#2101) --- .../components/WalletDrawer/WalletDrawer.tsx | 4 ++-- .../components/WalletDrawer/WalletItem.tsx | 18 ++++++++--------- .../widgets/connect/components/WalletItem.tsx | 20 +++++++++---------- .../widgets/connect/components/WalletList.tsx | 8 ++++---- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletDrawer.tsx b/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletDrawer.tsx index b749618a84..b89983c0a0 100644 --- a/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletDrawer.tsx +++ b/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletDrawer.tsx @@ -119,8 +119,8 @@ export function WalletDrawer({ key={providerDetail.info.rdns} testId={testId} loading={walletItemLoading} - providerDetail={providerDetail} - onWalletItemClick={handleWalletItemClick} + providerInfo={providerDetail.info} + onWalletItemClick={() => handleWalletItemClick(providerDetail)} rc={( )} diff --git a/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletItem.tsx b/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletItem.tsx index c95134394a..d6056a015d 100644 --- a/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletItem.tsx +++ b/packages/checkout/widgets-lib/src/components/WalletDrawer/WalletItem.tsx @@ -1,15 +1,15 @@ import { MenuItem } from '@biom3/react'; import { cloneElement, ReactElement, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { EIP6963ProviderDetail } from '@imtbl/checkout-sdk'; +import { EIP6963ProviderInfo } from '@imtbl/checkout-sdk'; import { RawImage } from '../RawImage/RawImage'; export interface WalletItemProps { loading?: boolean; recommended?: boolean; testId: string; - providerDetail: EIP6963ProviderDetail; - onWalletItemClick: (providerDetail: EIP6963ProviderDetail) => Promise; + providerInfo: EIP6963ProviderInfo; + onWalletItemClick: () => void; rc?: RC; } @@ -20,7 +20,7 @@ export function WalletItem< testId, loading = false, recommended = false, - providerDetail, + providerInfo, onWalletItemClick, }: WalletItemProps) { const { t } = useTranslation(); @@ -34,27 +34,27 @@ export function WalletItem< setBusy(true); // let the parent handle errors try { - await onWalletItemClick(providerDetail); + await onWalletItemClick(); } finally { setBusy(false); } }, })} - testId={`${testId}-wallet-list-${providerDetail.info.rdns}`} + testId={`${testId}-wallet-list-${providerInfo.rdns}`} size="medium" emphasized sx={{ position: 'relative' }} > - {providerDetail.info.name} + {providerInfo.name} {((recommended || busy) && ( { loading?: boolean; recommended?: boolean; - onWalletItemClick: (providerDetail: EIP6963ProviderDetail) => void; - providerDetail: EIP6963ProviderDetail; + onWalletItemClick: () => void; + providerInfo: EIP6963ProviderInfo; rc?: RC; } @@ -20,13 +20,13 @@ export function WalletItem< rc = , loading = false, recommended = false, - providerDetail, + providerInfo, onWalletItemClick, }: WalletProps) { const { t } = useTranslation(); const { isSmallScreenMode } = useIsSmallScreen(); const [busy, setBusy] = useState(false); - const providerSlug = getProviderSlugFromRdns(providerDetail.info.rdns); + const providerSlug = getProviderSlugFromRdns(providerInfo.rdns); const isPassport = providerSlug === WalletProviderName.PASSPORT; const isPassportOrMetamask = isPassport || providerSlug === WalletProviderName.METAMASK; const offsetStyles = { marginLeft: '65px' }; @@ -39,13 +39,13 @@ export function WalletItem< setBusy(true); // let the parent handle errors try { - await onWalletItemClick(providerDetail); + await onWalletItemClick(); } finally { setBusy(false); } }, })} - testId={`wallet-list-${providerDetail.info.rdns}`} + testId={`wallet-list-${providerInfo.rdns}`} size="medium" emphasized sx={{ @@ -54,8 +54,8 @@ export function WalletItem< }} > ))} - {providerDetail.info.name} + {providerInfo.name} {(!busy && )} diff --git a/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx b/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx index 8ff1b32cc9..6ca219c94e 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/components/WalletList.tsx @@ -372,8 +372,8 @@ export function WalletList(props: WalletListProps) { handleWalletItemClick(passportProviderDetail)} + providerInfo={passportProviderDetail.info} rc={( handleWalletItemClick(filteredProviders[0])} + providerInfo={filteredProviders[0].info} rc={( Date: Wed, 21 Aug 2024 12:34:19 +1000 Subject: [PATCH 19/29] Add primary sales backend api example (#2103) --- .../primary-sales-backend-api/.env.example | 9 + examples/primary-sales-backend-api/.gitignore | 4 + examples/primary-sales-backend-api/.nvmrc | 1 + examples/primary-sales-backend-api/README.md | 40 ++++ .../docker-compose.yml | 18 ++ .../primary-sales-backend-api/package.json | 29 +++ .../Primary sales BE.postman_collection.json | 189 ++++++++++++++++++ .../20240820102407_init/migration.sql | 65 ++++++ .../prisma/migrations/migration_lock.toml | 3 + .../prisma/schema.prisma | 72 +++++++ .../primary-sales-backend-api/prisma/seed.ts | 86 ++++++++ .../primary-sales-backend-api/src/errors.ts | 8 + .../src/plugins/errorHander.ts | 45 +++++ .../src/plugins/prisma.ts | 17 ++ .../src/plugins/swagger.ts | 33 +++ .../src/routes/authorize.ts | 127 ++++++++++++ .../src/routes/confirm.ts | 45 +++++ .../src/routes/expire.ts | 78 ++++++++ .../src/routes/products.ts | 45 +++++ .../src/routes/quotes.ts | 124 ++++++++++++ .../src/schemas/currency.ts | 7 + .../src/schemas/product.ts | 17 ++ .../primary-sales-backend-api/src/server.ts | 60 ++++++ .../primary-sales-backend-api/tsconfig.json | 11 + 24 files changed, 1133 insertions(+) create mode 100644 examples/primary-sales-backend-api/.env.example create mode 100644 examples/primary-sales-backend-api/.gitignore create mode 100644 examples/primary-sales-backend-api/.nvmrc create mode 100644 examples/primary-sales-backend-api/README.md create mode 100644 examples/primary-sales-backend-api/docker-compose.yml create mode 100644 examples/primary-sales-backend-api/package.json create mode 100644 examples/primary-sales-backend-api/postman/Primary sales BE.postman_collection.json create mode 100644 examples/primary-sales-backend-api/prisma/migrations/20240820102407_init/migration.sql create mode 100644 examples/primary-sales-backend-api/prisma/migrations/migration_lock.toml create mode 100644 examples/primary-sales-backend-api/prisma/schema.prisma create mode 100644 examples/primary-sales-backend-api/prisma/seed.ts create mode 100644 examples/primary-sales-backend-api/src/errors.ts create mode 100644 examples/primary-sales-backend-api/src/plugins/errorHander.ts create mode 100644 examples/primary-sales-backend-api/src/plugins/prisma.ts create mode 100644 examples/primary-sales-backend-api/src/plugins/swagger.ts create mode 100644 examples/primary-sales-backend-api/src/routes/authorize.ts create mode 100644 examples/primary-sales-backend-api/src/routes/confirm.ts create mode 100644 examples/primary-sales-backend-api/src/routes/expire.ts create mode 100644 examples/primary-sales-backend-api/src/routes/products.ts create mode 100644 examples/primary-sales-backend-api/src/routes/quotes.ts create mode 100644 examples/primary-sales-backend-api/src/schemas/currency.ts create mode 100644 examples/primary-sales-backend-api/src/schemas/product.ts create mode 100644 examples/primary-sales-backend-api/src/server.ts create mode 100644 examples/primary-sales-backend-api/tsconfig.json diff --git a/examples/primary-sales-backend-api/.env.example b/examples/primary-sales-backend-api/.env.example new file mode 100644 index 0000000000..028f05c759 --- /dev/null +++ b/examples/primary-sales-backend-api/.env.example @@ -0,0 +1,9 @@ +PORT=3000 + +# Environment variables declared in this file are automatically made available to Prisma. +# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema + +# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. +# See the documentation for all the connection string options: https://pris.ly/d/connection-strings + +DATABASE_URL="postgresql://postgres:postgres@localhost:5432/primarysales?schema=public" diff --git a/examples/primary-sales-backend-api/.gitignore b/examples/primary-sales-backend-api/.gitignore new file mode 100644 index 0000000000..12a6c18dc0 --- /dev/null +++ b/examples/primary-sales-backend-api/.gitignore @@ -0,0 +1,4 @@ +node_modules +# Keep environment variables out of version control +.env +build \ No newline at end of file diff --git a/examples/primary-sales-backend-api/.nvmrc b/examples/primary-sales-backend-api/.nvmrc new file mode 100644 index 0000000000..b427e2ae2f --- /dev/null +++ b/examples/primary-sales-backend-api/.nvmrc @@ -0,0 +1 @@ +v20.16.0 \ No newline at end of file diff --git a/examples/primary-sales-backend-api/README.md b/examples/primary-sales-backend-api/README.md new file mode 100644 index 0000000000..0dee9cc627 --- /dev/null +++ b/examples/primary-sales-backend-api/README.md @@ -0,0 +1,40 @@ +# Example Primary Sales Webhook API + +This example shows how to implement the webhooks required for the [primary sales backend config](https://docs.immutable.com/products/zkEVM/checkout/widgets/primary-sales/backend/byo). + +## Pre-requisites + +* [NodeJS >= v20](https://nodejs.org/en) +* [Docker](https://www.docker.com/) + +### Install dependencies + +Run `npm i` + +### Set environment variables + +Copy the `.env.example` file and rename it to `.env`. + +## Running the app + +1. Run `docker-compose up -d` to start the postgres DB at port 5432. +2. Run `npx prisma migrate dev` and `npm run seed` to initialise the DB schema and seed it with data. +3. `npm run dev` to start your server on port 3000 + +## Webhook endpoints + +To see the list of endpoints this example serves, go to [the Swagger UI](http://localhost:3000/docs). + +Apart from the `/api/v1/products` endpoint which is used to list the products available in the DB, the rest of the endpoints correspond to the [Primary Sales backend config documentation](https://docs.immutable.com/products/zkEVM/checkout/widgets/primary-sales/backend/byo). + + +## Example requests + +For your convenience, we have also added a postman collection under the `postman` folder. These contain sample requests for each endpoint, using the seeded products data. + +To run the requests, download [Postman](https://www.postman.com/) and import the collection. + + +## TO-DO list + +* Add authentication for each endpoint, as per the [webhook authentication section](https://docs.immutable.com/products/zkEVM/checkout/widgets/primary-sales/backend/byo#webhook-authentication) \ No newline at end of file diff --git a/examples/primary-sales-backend-api/docker-compose.yml b/examples/primary-sales-backend-api/docker-compose.yml new file mode 100644 index 0000000000..b15f216412 --- /dev/null +++ b/examples/primary-sales-backend-api/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.8' + +services: + primary-sales-db: + image: postgres:14 + ports: + - 5432:5432 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=primarysales + restart: always + volumes: + - primary-sales-db-data:/data/postgres + +volumes: + primary-sales-db-data: + diff --git a/examples/primary-sales-backend-api/package.json b/examples/primary-sales-backend-api/package.json new file mode 100644 index 0000000000..459bf355ea --- /dev/null +++ b/examples/primary-sales-backend-api/package.json @@ -0,0 +1,29 @@ +{ + "devDependencies": { + "@types/node": "^22.2.0", + "fastify-tsconfig": "^2.0.0", + "nodemon": "^3.1.4", + "prisma": "^5.18.0", + "ts-node": "^10.9.2", + "typescript": "^5.5.4" + }, + "dependencies": { + "@fastify/autoload": "^5.10.0", + "@fastify/env": "^4.4.0", + "@fastify/swagger": "^8.15.0", + "@fastify/swagger-ui": "^4.1.0", + "@fastify/type-provider-typebox": "^4.0.0", + "@paralleldrive/cuid2": "^2.2.2", + "@prisma/client": "^5.18.0", + "fastify": "^4.28.1" + }, + "prisma": { + "seed": "ts-node prisma/seed.ts" + }, + "scripts": { + "build": "rm -rf build ; tsc", + "start": "node build/src/server.js", + "dev": "nodemon --exec ts-node src/server.ts", + "seed": "prisma db seed" + } +} diff --git a/examples/primary-sales-backend-api/postman/Primary sales BE.postman_collection.json b/examples/primary-sales-backend-api/postman/Primary sales BE.postman_collection.json new file mode 100644 index 0000000000..4df0afbcdd --- /dev/null +++ b/examples/primary-sales-backend-api/postman/Primary sales BE.postman_collection.json @@ -0,0 +1,189 @@ +{ + "info": { + "_postman_id": "c754b503-fb61-4722-8fac-47fecc2efb3e", + "name": "Primary sales BE", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "25754861" + }, + "item": [ + { + "name": "Quote", + "request": { + "method": "POST", + "header": [ + { + "key": "QUOTE_API_KEY", + "value": "test_api_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"recipient_address\": \"0xdd9AAE1C317eE6EFEb0F3DB0A068e9Ed952a6CEB\",\n \"products\": [\n {\n \"product_id\": \"vi7age4ku18qynwbk4wx90ge\",\n \"quantity\": 1\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:3000/api/v1/orders/quotes", + "host": [ + "localhost" + ], + "port": "3000", + "path": [ + "api", + "v1", + "orders", + "quotes" + ] + } + }, + "response": [] + }, + { + "name": "Create order", + "request": { + "method": "POST", + "header": [ + { + "key": "QUOTE_API_KEY", + "value": "test_api_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"recipient_address\": \"0xdd9AAE1C317eE6EFEb0F3DB0A068e9Ed952a6CEB\",\n \"currency\": \"USDC\",\n \"products\": [\n {\n \"product_id\": \"vi7age4ku18qynwbk4wx90ge\",\n \"quantity\": 1\n },\n {\n \"product_id\": \"jtwrclpj0v1zab865ne893hb\",\n \"quantity\": 1\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:3000/api/v1/sale-authorization", + "host": [ + "localhost" + ], + "port": "3000", + "path": [ + "api", + "v1", + "sale-authorization" + ] + } + }, + "response": [] + }, + { + "name": "Expire an order", + "request": { + "method": "POST", + "header": [ + { + "key": "QUOTE_API_KEY", + "value": "test_api_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"reference\": \"cm02a70000001updhnudm7bop\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:3000/api/v1/expire", + "host": [ + "localhost" + ], + "port": "3000", + "path": [ + "api", + "v1", + "expire" + ] + } + }, + "response": [] + }, + { + "name": "Confirm", + "request": { + "method": "POST", + "header": [ + { + "key": "QUOTE_API_KEY", + "value": "test_api_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"reference\": \"cm02apig000035o3ipwszr02z\",\n \"tx_hash\": \"test\",\n \"recipient_address\": \"0xdd9AAE1C317eE6EFEb0F3DB0A068e9Ed952a6CEB\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:3000/api/v1/confirm", + "host": [ + "localhost" + ], + "port": "3000", + "path": [ + "api", + "v1", + "confirm" + ] + } + }, + "response": [] + }, + { + "name": "Products", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "QUOTE_API_KEY", + "value": "test_api_key", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"reference\": \"cm02a70000001updhnudm7bop\",\n \"tx_hash\": \"test\",\n \"recipient_address\": \"0xdd9AAE1C317eE6EFEb0F3DB0A068e9Ed952a6CEB\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:3000/api/v1/products", + "host": [ + "localhost" + ], + "port": "3000", + "path": [ + "api", + "v1", + "products" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/examples/primary-sales-backend-api/prisma/migrations/20240820102407_init/migration.sql b/examples/primary-sales-backend-api/prisma/migrations/20240820102407_init/migration.sql new file mode 100644 index 0000000000..00a238fd17 --- /dev/null +++ b/examples/primary-sales-backend-api/prisma/migrations/20240820102407_init/migration.sql @@ -0,0 +1,65 @@ +-- CreateEnum +CREATE TYPE "CurrencyType" AS ENUM ('crypto', 'fiat'); + +-- CreateEnum +CREATE TYPE "OrderStatus" AS ENUM ('reserved', 'completed', 'expired', 'failed'); + +-- CreateTable +CREATE TABLE "Product" ( + "id" TEXT NOT NULL, + "collectionAddress" TEXT NOT NULL, + "contractType" TEXT NOT NULL, + "stockQuantity" INTEGER NOT NULL, + + CONSTRAINT "Product_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Currency" ( + "name" TEXT NOT NULL, + "type" "CurrencyType" NOT NULL, + + CONSTRAINT "Currency_pkey" PRIMARY KEY ("name") +); + +-- CreateTable +CREATE TABLE "ProductPrice" ( + "product_id" TEXT NOT NULL, + "currency_name" TEXT NOT NULL, + "amount" DOUBLE PRECISION NOT NULL, + + CONSTRAINT "ProductPrice_pkey" PRIMARY KEY ("product_id","currency_name") +); + +-- CreateTable +CREATE TABLE "Order" ( + "id" TEXT NOT NULL, + "status" "OrderStatus" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "transactionHash" TEXT, + "recipientAddress" TEXT NOT NULL, + + CONSTRAINT "Order_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "OrderLineItem" ( + "order_id" TEXT NOT NULL, + "product_id" TEXT NOT NULL, + "quantity" INTEGER NOT NULL, + + CONSTRAINT "OrderLineItem_pkey" PRIMARY KEY ("order_id","product_id") +); + +-- AddForeignKey +ALTER TABLE "ProductPrice" ADD CONSTRAINT "ProductPrice_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "Product"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProductPrice" ADD CONSTRAINT "ProductPrice_currency_name_fkey" FOREIGN KEY ("currency_name") REFERENCES "Currency"("name") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "OrderLineItem" ADD CONSTRAINT "OrderLineItem_order_id_fkey" FOREIGN KEY ("order_id") REFERENCES "Order"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "OrderLineItem" ADD CONSTRAINT "OrderLineItem_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "Product"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/examples/primary-sales-backend-api/prisma/migrations/migration_lock.toml b/examples/primary-sales-backend-api/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000000..fbffa92c2b --- /dev/null +++ b/examples/primary-sales-backend-api/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/examples/primary-sales-backend-api/prisma/schema.prisma b/examples/primary-sales-backend-api/prisma/schema.prisma new file mode 100644 index 0000000000..3beb46bab9 --- /dev/null +++ b/examples/primary-sales-backend-api/prisma/schema.prisma @@ -0,0 +1,72 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + +generator client { + provider = "prisma-client-js" + binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Product { + id String @id @default(cuid()) + productPrices ProductPrice[] + collectionAddress String + contractType String + stockQuantity Int + orders OrderLineItem[] +} + +enum CurrencyType { + crypto + fiat +} + +model Currency { + name String @id + type CurrencyType + productPrices ProductPrice[] +} + +model ProductPrice { + product Product @relation(fields: [product_id], references: [id]) + product_id String + currency Currency @relation(fields: [currency_name], references: [name]) + currency_name String + amount Float + + @@id([product_id, currency_name]) +} + +enum OrderStatus { + reserved + completed + expired + failed +} + +model Order { + id String @id @default(cuid()) + status OrderStatus + lineItems OrderLineItem[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + transactionHash String? + recipientAddress String +} + +model OrderLineItem { + order_id String + product_id String + quantity Int + order Order @relation(fields: [order_id], references: [id]) + product Product @relation(fields: [product_id], references: [id]) + + @@id([order_id, product_id]) +} diff --git a/examples/primary-sales-backend-api/prisma/seed.ts b/examples/primary-sales-backend-api/prisma/seed.ts new file mode 100644 index 0000000000..c0400387c0 --- /dev/null +++ b/examples/primary-sales-backend-api/prisma/seed.ts @@ -0,0 +1,86 @@ +import { PrismaClient } from "@prisma/client"; +import 'dotenv/config' + +const prisma = new PrismaClient(); + +// For this seed script, we will create a few products and currencies +// that we will use to demonstrate the API functionality + +// This is a fake collection address. In a real scenario, this would be the address of the product's collection address. +const collectionAddress = '0x00'; + +async function main() { + const usdc = await prisma.currency.upsert({ + where: { name: 'USDC' }, + update: {}, + create: { + name: 'USDC', + type: 'crypto' + } + }); + + const eth = await prisma.currency.upsert({ + where: { name: 'ETH' }, + update: {}, + create: { + name: 'ETH', + type: 'crypto' + } + }); + + const productId1 = 'vi7age4ku18qynwbk4wx90ge'; + + await prisma.product.upsert({ + where: { id: productId1 }, + update: {}, + create: { + id: productId1, + collectionAddress: collectionAddress, + contractType: 'ERC721', + stockQuantity: 100, + productPrices: { + create: [ + { + currency_name: usdc.name, + amount: 1000 + }, + { + currency_name: eth.name, + amount: 0.205 + }, + ] + } + } + }) + + const productId2 = 'jtwrclpj0v1zab865ne893hb'; + + await prisma.product.upsert({ + where: { id: productId2 }, + update: {}, + create: { + id: productId2, + collectionAddress: collectionAddress, + contractType: 'ERC721', + stockQuantity: 50, + productPrices: { + create: [ + { + currency_name: usdc.name, + amount: 20 + }, + ] + } + } + }) +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/errors.ts b/examples/primary-sales-backend-api/src/errors.ts new file mode 100644 index 0000000000..825fe2083a --- /dev/null +++ b/examples/primary-sales-backend-api/src/errors.ts @@ -0,0 +1,8 @@ +export class ApiError extends Error { + constructor(readonly statusCode: number, message: string) { + super(message); + this.statusCode = statusCode; + + Error.captureStackTrace(this, this.constructor); + } +} \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/plugins/errorHander.ts b/examples/primary-sales-backend-api/src/plugins/errorHander.ts new file mode 100644 index 0000000000..309db96f7a --- /dev/null +++ b/examples/primary-sales-backend-api/src/plugins/errorHander.ts @@ -0,0 +1,45 @@ +import { Prisma } from '@prisma/client'; +import { FastifyInstance, FastifyPluginAsync } from 'fastify'; +import fp from 'fastify-plugin'; + +const handlePrismaError = (err: Prisma.PrismaClientKnownRequestError): { + statusCode: number, + message: string +} => { + switch (err.code) { + case 'P2025': + return { + statusCode: 400, + message: `Not found: ${err.meta?.modelName}` + }; + default: + // handling all other errors + return { + statusCode: 500, + message: 'Internal Server Error' + }; + + } +}; + +const errorHandlerPlugin: FastifyPluginAsync = fp(async (fastify: FastifyInstance) => { + fastify.setErrorHandler(function (error, request, reply) { + this.log.error(error); + + if (error instanceof Prisma.PrismaClientKnownRequestError) { + const mappedError = handlePrismaError(error); + + reply.status(mappedError.statusCode).send({ message: mappedError.message }); + return; + } + + if (!error.statusCode) { + reply.status(500).send({ message: 'Internal Server Error' }); + return; + } + + reply.status(error.statusCode).send({ message: error.message }); + }); +}); + +export default errorHandlerPlugin; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/plugins/prisma.ts b/examples/primary-sales-backend-api/src/plugins/prisma.ts new file mode 100644 index 0000000000..97da5f1229 --- /dev/null +++ b/examples/primary-sales-backend-api/src/plugins/prisma.ts @@ -0,0 +1,17 @@ +import { PrismaClient } from "@prisma/client"; +import { FastifyPluginAsync } from "fastify"; +import fp from 'fastify-plugin' + +const PrismaPlugin: FastifyPluginAsync = fp(async (fastify) => { + const prisma = new PrismaClient(); + + await prisma.$connect(); + + fastify.decorate('prisma', prisma) + + fastify.addHook('onClose', async () => { + await prisma.$disconnect(); + }); +}) + +export default PrismaPlugin; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/plugins/swagger.ts b/examples/primary-sales-backend-api/src/plugins/swagger.ts new file mode 100644 index 0000000000..428651e679 --- /dev/null +++ b/examples/primary-sales-backend-api/src/plugins/swagger.ts @@ -0,0 +1,33 @@ +import fp from 'fastify-plugin' +import SwaggerUI from '@fastify/swagger-ui' +import Swagger, { type FastifyDynamicSwaggerOptions } from '@fastify/swagger' + +export default fp(async (fastify, opts) => { + await fastify.register(Swagger, { + openapi: { + info: { + title: 'Primary Sales Webhooks Backend', + description: 'Example API endpoints for the Primary Sales Webhooks Backend', + version: '0.1.0', + }, + servers: [ + { + url: `http://localhost:${fastify.config.PORT}`, + }, + ], + components: { + securitySchemes: { + bearerAuth: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + }, + }) + + await fastify.register(SwaggerUI, { + routePrefix: '/docs', + }) +}) \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/routes/authorize.ts b/examples/primary-sales-backend-api/src/routes/authorize.ts new file mode 100644 index 0000000000..d2a1a988ac --- /dev/null +++ b/examples/primary-sales-backend-api/src/routes/authorize.ts @@ -0,0 +1,127 @@ +import { FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox"; +import { OrderLineItem, OrderStatus, PrismaClient } from '@prisma/client'; +import { ApiError } from '../errors'; +import { ProductRequestSchema, ProductRequestType } from "../schemas/product"; + +const createOrder = async (prisma: PrismaClient, recipientAddress: string, orderProducts: ProductRequestType[]) => { + return await prisma.$transaction(async tx => { + const updatedProducts = []; + + for (const orderProduct of orderProducts) { + + // For each product in the order, we decrement the stock quantity by the order quantity since we are reserving stock for the order. + const updatedProduct = await tx.product.update({ + where: { id: orderProduct.product_id }, + data: { + stockQuantity: { decrement: orderProduct.quantity } + }, + include: { + productPrices: true + } + }) + + if (updatedProduct.stockQuantity < 0) { + throw new ApiError(400, `Product with id ${orderProduct.product_id} has insufficient stock for this order`); + } + updatedProducts.push(updatedProduct); + } + + // Create an order with a 'reserved' status alongside the order line items. + const order = await tx.order.create({ + data: { + status: OrderStatus.reserved, + recipientAddress: recipientAddress, + lineItems: { + create: updatedProducts.map((product) => ({ + product_id: product.id, + quantity: orderProducts.find((orderProduct) => orderProduct.product_id === product.id)?.quantity ?? 0 + })), + } + }, + include: { + lineItems: { + include: { + product: { + include: { + productPrices: true + } + } + } + } + } + }) + return order; + }) +} + +const SaleAuthorizationRoutes: FastifyPluginAsyncTypebox = async (fastify) => { + fastify.post('/orders/authorize', { + schema: { + description: 'Authorize a sale and reserve stock for the order', + body: Type.Object({ + products: Type.Array(ProductRequestSchema), + currency: Type.String(), + recipient_address: Type.String() + }), + response: { + 200: Type.Object({ + reference: Type.String(), + currency: Type.String(), + products: Type.Array(Type.Object({ + product_id: Type.String(), + collection_address: Type.String(), + contract_type: Type.String(), + detail: Type.Array(Type.Object({ + token_id: Type.String(), + amount: Type.Number() + }) + ) + })) + }), + 400: Type.Object({ + message: Type.String() + }), + 404: Type.Object({ + message: Type.String() + }), + } + } + }, async (request, _) => { + const order = await createOrder(fastify.prisma, request.body.recipient_address, request.body.products); + + const populateDetails = (amount: number, lineItem: OrderLineItem) => { + const details = []; + for (let i = 0; i < lineItem.quantity; i++) { + details.push({ + // We don't persist token ID in this example, so we generate a random one. + // For real life use cases, consider whether you need to persist token_id or not during order creation. + token_id: String(Math.floor(Math.random() * 10000000000)), + amount + }) + } + + return details; + } + + return { + reference: order.id, + currency: request.body.currency, + products: order.lineItems.map(lineItem => { + const pricing = lineItem.product.productPrices.find((productPrice) => productPrice.currency_name === request.body.currency); + if (!pricing) { + throw new ApiError(404, `Product with id ${lineItem.product_id} does not have pricing for currency ${request.body.currency}`); + } + const productDetails = populateDetails(pricing.amount, lineItem); + + return { + product_id: lineItem.product_id, + collection_address: lineItem.product.collectionAddress, + contract_type: lineItem.product.contractType, + detail: productDetails + } + }) + } + }); +} + +export default SaleAuthorizationRoutes; diff --git a/examples/primary-sales-backend-api/src/routes/confirm.ts b/examples/primary-sales-backend-api/src/routes/confirm.ts new file mode 100644 index 0000000000..0dfa2e722f --- /dev/null +++ b/examples/primary-sales-backend-api/src/routes/confirm.ts @@ -0,0 +1,45 @@ +import { FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox"; +import { OrderStatus } from "@prisma/client"; + +const ConfirmOrderRequestSchema = Type.Object({ + // This example doesn't need the rest of the fields in the request + // Consider what fields you'll need for your own implementation and adjust accordingly + reference: Type.String(), + tx_hash: Type.String(), +}) + + +const OrderConfirmationRoutes: FastifyPluginAsyncTypebox = async (fastify) => { + fastify.post('/orders/confirm', { + schema: { + description: 'Endpoint that will be called after a successful transation.', + body: ConfirmOrderRequestSchema, + response: { + 200: Type.Null(), + 404: Type.Object({ + message: Type.String() + }), + 400: Type.Object({ + message: Type.String() + }), + } + } + }, async (request, reply) => { + const { reference, tx_hash } = request.body; + + // We only update the order status to completed and store the transaction hash + // In real life scenarios you can use this endpoint for randomised metadata generation (such as lootboxes), to transfer the NFTs to the user in-game, etc. + await fastify.prisma.order.update({ + where: { + id: reference + }, + data: { + status: OrderStatus.completed, + transactionHash: tx_hash, + } + }); + return reply.status(200).send(); + }); +} + +export default OrderConfirmationRoutes; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/routes/expire.ts b/examples/primary-sales-backend-api/src/routes/expire.ts new file mode 100644 index 0000000000..3d5fd54d7f --- /dev/null +++ b/examples/primary-sales-backend-api/src/routes/expire.ts @@ -0,0 +1,78 @@ +import { FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox"; +import { OrderStatus, PrismaClient } from "@prisma/client"; +import { ApiError } from "../errors"; + +const expireOrder = async (prisma: PrismaClient, reference: string) => { + return await prisma.$transaction(async tx => { + const order = await tx.order.findUnique({ + where: { + id: reference + } + }); + + if (!order) { + throw new ApiError(404, 'Order not found'); + } + + if (order.status !== OrderStatus.reserved) { + throw new ApiError(400, 'Order is not reserved'); + } + + await tx.order.update({ + where: { + id: reference + }, + data: { + status: OrderStatus.expired + } + }); + + const lineItems = await tx.orderLineItem.findMany({ + where: { + order_id: reference + } + }); + + for (const lineItem of lineItems) { + await tx.product.update({ + where: { + id: lineItem.product_id + }, + // Since the order is expired, the quantity reserved by that order should be released back + // so we increase the stock back by the original order quantity + data: { + stockQuantity: { + increment: lineItem.quantity + } + } + }); + } + }); +} + + +const OrderExpiryRoutes: FastifyPluginAsyncTypebox = async (fastify) => { + fastify.post('/orders/expire', { + schema: { + description: 'Expire an order and release the reserved stock back to the product', + body: Type.Object({ + reference: Type.String(), + }), + response: { + 200: Type.Null(), + 404: Type.Object({ + message: Type.String() + }), + 400: Type.Object({ + message: Type.String() + }), + } + } + }, async (request, reply) => { + await expireOrder(fastify.prisma, request.body.reference); + + return reply.status(200).send(); + }); +} + +export default OrderExpiryRoutes; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/routes/products.ts b/examples/primary-sales-backend-api/src/routes/products.ts new file mode 100644 index 0000000000..e3a1106c3c --- /dev/null +++ b/examples/primary-sales-backend-api/src/routes/products.ts @@ -0,0 +1,45 @@ +import { FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox"; + +const OrderConfirmationRoutes: FastifyPluginAsyncTypebox = async (fastify) => { + fastify.get('/products', { + schema: { + description: 'Get a list of products with their pricing', + response: { + 200: Type.Array(Type.Object({ + product_id: Type.String(), + quantity: Type.Number(), + pricing: Type.Array(Type.Object({ + currency: Type.String(), + amount: Type.Number() + })) + })), + 404: Type.Object({ + message: Type.String() + }), + 400: Type.Object({ + message: Type.String() + }), + } + } + }, async () => { + const products = await fastify.prisma.product.findMany({ + include: { + productPrices: true + } + }); + return products.map(p => { + return { + product_id: p.id, + quantity: p.stockQuantity, + pricing: p.productPrices.map(pp => { + return { + currency: pp.currency_name, + amount: pp.amount + } + }) + } + }) + }); +} + +export default OrderConfirmationRoutes; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/routes/quotes.ts b/examples/primary-sales-backend-api/src/routes/quotes.ts new file mode 100644 index 0000000000..88decc4b24 --- /dev/null +++ b/examples/primary-sales-backend-api/src/routes/quotes.ts @@ -0,0 +1,124 @@ +import { FastifyPluginAsyncTypebox, Type } from "@fastify/type-provider-typebox"; +import { PrismaClient, Currency, CurrencyType } from "@prisma/client"; +import { CurrencySchema } from "../schemas/currency"; +import { ProductsResponseSchema, ProductsResponseType } from "../schemas/product"; +import { ApiError } from "../errors"; + +const getProductsWithPrices = (ids: string[], prisma: PrismaClient) => { + return prisma.product.findMany({ + where: { + id: { + in: ids + } + }, + include: { + productPrices: { + include: { + currency: true + } + } + } + }); +} + +const calculateTotals = (products: ProductsResponseType): Map => { + const currencyTotalsMap = new Map(); + + products.forEach((product) => { + product.pricing.forEach((productPrice) => { + const { currency, amount, currency_type } = productPrice; + + const currentTotal = currencyTotalsMap.get(currency)?.total || 0; + + currencyTotalsMap.set(currency, { + type: currency_type as CurrencyType, + name: currency, + total: currentTotal + amount + }); + }); + }); + + return currencyTotalsMap; +} + +const QuoteRoutes: FastifyPluginAsyncTypebox = async (fastify) => { + fastify.post('/quotes', { + schema: { + description: 'Get a quote for a list of products. Used to calculate the total cost of an order and show it to the user.', + body: Type.Object({ + recipient_address: Type.String(), + products: Type.Array(Type.Object({ + product_id: Type.String(), + quantity: Type.Integer() + })), + }), + response: { + 200: Type.Object({ + products: ProductsResponseSchema, + totals: Type.Array(CurrencySchema) + }), + 404: Type.Object({ + message: Type.String() + }), + 400: Type.Object({ + message: Type.String() + }), + } + } + }, async (request, _) => { + const { products: requestedProducts } = request.body; + + const products = await getProductsWithPrices(requestedProducts.map((product) => product.product_id), fastify.prisma); + + if (!products.length) { + return { products: [], totals: [] } + } + + const productsResponse: ProductsResponseType = []; + + for (const requestedProduct of requestedProducts) { + const product = products.find(p => p.id === requestedProduct.product_id); + + if (!product) { + throw new ApiError(404, `Product with id ${requestedProduct.product_id} not found`); + } + + if (requestedProduct.quantity > product.stockQuantity) { + throw new ApiError(400, `Not enough stock for product with id ${requestedProduct.product_id}`); + } + + // Get the pricing for the product, separated by currency + const productPrices = product.productPrices.map((productPrice) => ({ + currency: productPrice.currency.name, + amount: productPrice.amount * requestedProduct.quantity, + currency_type: String(productPrice.currency.type), + })); + + productsResponse.push({ + product_id: product.id, + quantity: requestedProduct.quantity, + pricing: productPrices + }); + } + + // Calculate totals for each currency + const currencyTotalsMap = calculateTotals(productsResponse); + + const totalsResponse = Array.from(currencyTotalsMap.values()).map(total => ({ + currency: total.name, + currency_type: String(total.type), + amount: total.total + })); + + return { + products: productsResponse, + totals: totalsResponse + } + }); +} + +export default QuoteRoutes; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/schemas/currency.ts b/examples/primary-sales-backend-api/src/schemas/currency.ts new file mode 100644 index 0000000000..f6539dafd9 --- /dev/null +++ b/examples/primary-sales-backend-api/src/schemas/currency.ts @@ -0,0 +1,7 @@ +import { Type } from "@fastify/type-provider-typebox"; + +export const CurrencySchema = Type.Object({ + currency: Type.String(), + amount: Type.Number(), + currency_type: Type.String(), +}) \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/schemas/product.ts b/examples/primary-sales-backend-api/src/schemas/product.ts new file mode 100644 index 0000000000..f1d005d170 --- /dev/null +++ b/examples/primary-sales-backend-api/src/schemas/product.ts @@ -0,0 +1,17 @@ +import { Type, Static } from "@fastify/type-provider-typebox"; +import { CurrencySchema } from "./currency"; + +export const ProductRequestSchema = Type.Object({ + product_id: Type.String(), + quantity: Type.Integer() +}); + +export type ProductRequestType = Static; + +export const ProductsResponseSchema = Type.Array(Type.Object({ + product_id: Type.String(), + quantity: Type.Number(), + pricing: Type.Array(CurrencySchema) +})); + +export type ProductsResponseType = Static; \ No newline at end of file diff --git a/examples/primary-sales-backend-api/src/server.ts b/examples/primary-sales-backend-api/src/server.ts new file mode 100644 index 0000000000..6ec408ff6c --- /dev/null +++ b/examples/primary-sales-backend-api/src/server.ts @@ -0,0 +1,60 @@ +import fastify from "fastify"; +import fastifyEnv from "@fastify/env"; +import AutoLoad from '@fastify/autoload'; +import { PrismaClient } from "@prisma/client"; +import { Static, Type } from "@fastify/type-provider-typebox"; + +export const ConfigSchema = Type.Object({ + PORT: Type.String({ default: '3000' }), +}); + +export type Config = Static; + +declare module 'fastify' { + interface FastifyInstance { + config: Config; + prisma: PrismaClient; + } +} + +const options = { + schema: ConfigSchema, + dotenv: true, + data: process.env +} + +const server = fastify({ logger: true }); + +const initialize = async () => { + await server + .register(fastifyEnv, options); + + server + .register(AutoLoad, { + dir: `${__dirname}/plugins`, + ignorePattern: /.test.(t|j)s/, + }) + .register(AutoLoad, { + dir: `${__dirname}/routes`, + ignorePattern: /.test.(t|j)s/, + dirNameRoutePrefix: true, + routeParams: true, + options: { prefix: "/api/v1" }, + }); + + await server.after(); +} + +(async () => { + try { + await initialize(); + await server.ready(); + await server.listen({ + port: Number(server.config.PORT), + host: '0.0.0.0' + }); + } catch (error) { + server.log.error(error); + process.exit(1); + } +})(); diff --git a/examples/primary-sales-backend-api/tsconfig.json b/examples/primary-sales-backend-api/tsconfig.json new file mode 100644 index 0000000000..96b6b0e58f --- /dev/null +++ b/examples/primary-sales-backend-api/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "fastify-tsconfig", + "compilerOptions": { + "outDir": "build", + "lib": ["es2018"], + "target": "es2018", + "strict": true, + "forceConsistentCasingInFileNames": true, + "typeRoots": ["./node_modules/@types", "./src/types"] + } +} \ No newline at end of file From 5fe632ab49ebc3c012324eef68c7cc21088a9598 Mon Sep 17 00:00:00 2001 From: Nik <2661899+CodeSchwert@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:50:30 +1200 Subject: [PATCH 20/29] fix: game bridge track function (#2104) --- packages/game-bridge/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/game-bridge/src/index.ts b/packages/game-bridge/src/index.ts index c098197185..e5cab98f4d 100644 --- a/packages/game-bridge/src/index.ts +++ b/packages/game-bridge/src/index.ts @@ -736,7 +736,7 @@ window.callFunction = async (jsonData: string) => { } case trackFunction: { const request = JSON.parse(data); - const properties = JSON.parse(request.properties); + const properties = request.properties ? JSON.parse(request.properties) : {}; track(request.moduleName, request.eventName, properties); callbackToGame({ responseFor: fxName, From 5c06f0e03b9b5bbc2d7298aeeb1f8a34c4741b25 Mon Sep 17 00:00:00 2001 From: Jimmy Hardwick Date: Wed, 21 Aug 2024 13:43:17 +1000 Subject: [PATCH 21/29] eip6963 proxying connect flow (#2090) Co-authored-by: Jhonatan Gonzalez --- .../postMessageEventTypes.ts | 1 + .../context/CheckoutContextProvider.tsx | 7 +- .../checkout/hooks/useEip6963Relayer.ts | 42 ++++++ .../checkout/hooks/useProviderRelay.ts | 121 ++++++++++++++++++ .../src/widgets/checkout/utils/config.ts | 19 +++ .../checkout/views/CheckoutAppIframe.tsx | 42 +++--- 6 files changed, 202 insertions(+), 30 deletions(-) create mode 100644 packages/checkout/widgets-lib/src/widgets/checkout/hooks/useEip6963Relayer.ts create mode 100644 packages/checkout/widgets-lib/src/widgets/checkout/hooks/useProviderRelay.ts diff --git a/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts b/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts index a34e0f6d74..81f168b01d 100644 --- a/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts +++ b/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts @@ -2,6 +2,7 @@ export enum PostMessageHandlerEventType { SYN = 'IMTBL_POST_MESSAGE_SYN', ACK = 'IMTBL_POST_MESSAGE_ACK', PROVIDER_RELAY = 'IMTBL_PROVIDER_RELAY', + PROVIDER_UPDATED = 'IMTBL_PROVIDER_UPDATED', EIP_6963_EVENT = 'IMTBL_EIP_6963_EVENT', WIDGET_EVENT = 'IMTBL_CHECKOUT_WIDGET_EVENT', } diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/context/CheckoutContextProvider.tsx b/packages/checkout/widgets-lib/src/widgets/checkout/context/CheckoutContextProvider.tsx index 995142d102..965326ebcf 100644 --- a/packages/checkout/widgets-lib/src/widgets/checkout/context/CheckoutContextProvider.tsx +++ b/packages/checkout/widgets-lib/src/widgets/checkout/context/CheckoutContextProvider.tsx @@ -52,17 +52,14 @@ export function CheckoutContextProvider({ }, [iframeContentWindow, checkout, iframeURL]); useEffect(() => { - if (!provider || !postMessageHandler) return undefined; + if (!provider || !postMessageHandler) return; + checkoutDispatch({ payload: { type: CheckoutActions.SET_PROVIDER_RELAY, providerRelay: new ProviderRelay(postMessageHandler, provider), }, }); - - return () => { - postMessageHandler?.destroy(); - }; }, [provider, postMessageHandler]); return ( diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useEip6963Relayer.ts b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useEip6963Relayer.ts new file mode 100644 index 0000000000..c7995640be --- /dev/null +++ b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useEip6963Relayer.ts @@ -0,0 +1,42 @@ +import { useCallback, useEffect } from 'react'; +import { EIP6963ProviderDetail, PostMessageHandlerEventType } from '@imtbl/checkout-sdk'; +import { useCheckoutContext } from '../context/CheckoutContextProvider'; + +export function useEip6963Relayer() { + const [checkoutState] = useCheckoutContext(); + const { postMessageHandler } = checkoutState; + + const onAnnounce = useCallback((event: CustomEvent) => { + postMessageHandler?.send(PostMessageHandlerEventType.EIP_6963_EVENT, { + message: 'eip6963:announceProvider', + info: event.detail.info, + }); + }, [postMessageHandler]); + + useEffect( + () => { + if (!postMessageHandler) return () => { }; + + window.addEventListener('eip6963:announceProvider', onAnnounce as any); + + return () => window.removeEventListener('eip6963:announceProvider', onAnnounce as any); + }, + [postMessageHandler, onAnnounce], + ); + + const onRequest = useCallback((payload: any) => { + if (payload.message !== 'eip6963:requestProvider') return; + + window.dispatchEvent(new CustomEvent('eip6963:requestProvider')); + }, [postMessageHandler]); + + useEffect(() => { + if (!postMessageHandler) return; + + postMessageHandler.subscribe((message) => { + if (message.type === PostMessageHandlerEventType.EIP_6963_EVENT) { + onRequest(message.payload); + } + }); + }, [postMessageHandler, onRequest]); +} diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useProviderRelay.ts b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useProviderRelay.ts new file mode 100644 index 0000000000..e2906d1ba7 --- /dev/null +++ b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useProviderRelay.ts @@ -0,0 +1,121 @@ +import { useCallback, useEffect } from 'react'; +import { + EIP6963ProviderInfo, + PostMessageData, + PostMessageHandlerEventType, +} from '@imtbl/checkout-sdk'; +import { Web3Provider } from '@ethersproject/providers'; +import { useCheckoutContext } from '../context/CheckoutContextProvider'; +import { CheckoutActions } from '../context/CheckoutContext'; + +// TODO these types should be in sync with Checkout App +type MessageId = number | string | null; + +interface JsonRpcRequestMessage { + type: 'dapp'; + jsonrpc: '2.0'; + // Optional in the request. + id?: MessageId; + method: string; + params?: TParams; +} + +type ProviderRelayPayload = { + jsonRpcRequestMessage: JsonRpcRequestMessage; + eip6963Info: EIP6963ProviderInfo; +}; + +export function useProviderRelay() { + const [{ checkout, postMessageHandler, provider }, checkoutDispatch] = useCheckoutContext(); + + /** + * Execute a request using the provider + * and relay the response back using the postMessageHandler + */ + const execute = useCallback( + async (payload: ProviderRelayPayload, executeProvider: Web3Provider) => { + if (!executeProvider?.provider.request) { + throw new Error("Provider only supports 'request' method"); + } + + if (!postMessageHandler) { + throw new Error( + 'Provider can execute request because PostMessageHandler is not initialized', + ); + } + + const { id, params, method } = payload.jsonRpcRequestMessage; + + // Execute the request + const result = await executeProvider.provider.request({ method, params }); + const formattedResponse = { id, result, jsonrpc: '2.0' }; + + // Send the response using the postMessageHandler + postMessageHandler.send(PostMessageHandlerEventType.PROVIDER_RELAY, { + response: formattedResponse, + eip6963Info: payload.eip6963Info, + }); + }, + [postMessageHandler], + ); + + /** + * Handle incoming provider relay messages + */ + const onJsonRpcRequestMessage = useCallback( + async ({ type, payload }: PostMessageData) => { + if (!postMessageHandler || !checkout) return; + if (type !== PostMessageHandlerEventType.PROVIDER_RELAY) return; + + const providerRelayPayload = payload as ProviderRelayPayload; + + const injectedProviders = checkout.getInjectedProviders(); + const targetProvider = injectedProviders.find( + (p) => p.info.uuid === providerRelayPayload.eip6963Info.uuid, + ); + + if (!targetProvider) { + // eslint-disable-next-line no-console + console.error( + 'PARENT - requested provider not found', + providerRelayPayload.eip6963Info, + injectedProviders, + ); + return; + } + + // If provider is not defined, connect the target provider + let currentProvider = provider; + if (!currentProvider) { + const connectResponse = await checkout.connect({ + provider: new Web3Provider(targetProvider.provider), + }); + currentProvider = connectResponse.provider; + } + + // Set provider and execute the request + checkoutDispatch({ + payload: { + type: CheckoutActions.SET_PROVIDER, + provider: currentProvider, + }, + }); + + postMessageHandler.send(PostMessageHandlerEventType.PROVIDER_UPDATED, { + eip6963Info: payload.eip6963Info, + }); + + await execute(providerRelayPayload, currentProvider); + }, + + [provider, postMessageHandler, checkout, execute], + ); + + /** + * Subscribe to provider relay messages + */ + useEffect(() => { + if (!postMessageHandler) return; + postMessageHandler.subscribe(onJsonRpcRequestMessage); + }, [provider, postMessageHandler, execute, onJsonRpcRequestMessage]); +} diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/utils/config.ts b/packages/checkout/widgets-lib/src/widgets/checkout/utils/config.ts index 19e9703eb3..a796a1e7fb 100644 --- a/packages/checkout/widgets-lib/src/widgets/checkout/utils/config.ts +++ b/packages/checkout/widgets-lib/src/widgets/checkout/utils/config.ts @@ -2,3 +2,22 @@ * The timeout in milliseconds for the iframe to be initialized. */ export const IFRAME_INIT_TIMEOUT_MS = 10000; + +/** + * The permissions to allow on the iframe. + */ +export const IFRAME_ALLOW_PERMISSIONS = ` + accelerometer; + camera; + microphone; + geolocation; + gyroscope; + fullscreen; + autoplay; + encrypted-media; + picture-in-picture; + clipboard-write; + clipboard-read; +` + .trim() + .replace(/\n/g, ''); diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx b/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx index 07a5170a17..078b9110d0 100644 --- a/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx +++ b/packages/checkout/widgets-lib/src/widgets/checkout/views/CheckoutAppIframe.tsx @@ -16,21 +16,10 @@ import { sendCheckoutEvent } from '../CheckoutWidgetEvents'; import { EventTargetContext } from '../../../context/event-target-context/EventTargetContext'; import { LoadingView } from '../../../views/loading/LoadingView'; import { ErrorView } from '../../../views/error/ErrorView'; -import { IFRAME_INIT_TIMEOUT_MS } from '../utils/config'; +import { IFRAME_INIT_TIMEOUT_MS, IFRAME_ALLOW_PERMISSIONS } from '../utils/config'; +import { useEip6963Relayer } from '../hooks/useEip6963Relayer'; +import { useProviderRelay } from '../hooks/useProviderRelay'; -const permissions = ` - accelerometer; - camera; - microphone; - geolocation; - gyroscope; - fullscreen; - autoplay; - encrypted-media; - picture-in-picture; - clipboard-write; - clipboard-read; -`; export interface LoadingHandoverProps { text: string; duration?: number; @@ -48,6 +37,9 @@ export function CheckoutAppIframe() { checkoutDispatch, ] = useCheckoutContext(); + useEip6963Relayer(); + useProviderRelay(); + const loading = !iframeURL || !iframeContentWindow || !initialised; const { @@ -73,8 +65,10 @@ export function CheckoutAppIframe() { // subscribe to widget events postMessageHandler.subscribe(({ type, payload }) => { + if (type !== PostMessageHandlerEventType.WIDGET_EVENT) return; + // FIXME: improve typing - const event: { + const customEvent: { type: IMTBLWidgetEvents.IMTBL_CHECKOUT_WIDGET_EVENT; detail: { type: CheckoutEventType; @@ -82,19 +76,18 @@ export function CheckoutAppIframe() { }; } = payload as any; - if (type !== PostMessageHandlerEventType.WIDGET_EVENT) return; + // Forward widget events + sendCheckoutEvent(eventTarget, customEvent.detail); - // forward events - sendCheckoutEvent(eventTarget, event.detail); - - // check if the widget has been initialised - if (event.detail.type === CheckoutEventType.INITIALISED) { + // If iframe has been initialised, set widget as initialised + if (customEvent.detail.type === CheckoutEventType.INITIALISED) { setInitialised(true); clearTimeout(timeoutRef.current!); } }); - // check if loaded correctly + // Expire iframe initialisation after timeout + // and set a loading error timeoutRef.current = setTimeout(() => { if (!initialised) { setLoadingError(true); @@ -103,7 +96,6 @@ export function CheckoutAppIframe() { }, IFRAME_INIT_TIMEOUT_MS); return () => { - postMessageHandler.destroy(); clearTimeout(timeoutRef.current!); }; }, [postMessageHandler]); @@ -135,11 +127,11 @@ export function CheckoutAppIframe() {